1 /* 2 * Copyright (c) 2024 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_PATTERN_TEXT_TEXT_BASE_SELECT_OVERLAY_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_TEXT_TEXT_BASE_SELECT_OVERLAY_H 18 #include <optional> 19 20 #include "base/geometry/ng/point_t.h" 21 #include "base/geometry/ng/rect_t.h" 22 #include "base/memory/ace_type.h" 23 #include "base/memory/referenced.h" 24 #include "core/components_ng/manager/select_content_overlay/select_overlay_callback.h" 25 #include "core/components_ng/manager/select_content_overlay/select_overlay_holder.h" 26 #include "core/components_ng/pattern/scrollable/scrollable_paint_property.h" 27 #include "core/components_ng/pattern/select_overlay/select_overlay_property.h" 28 #include "core/components_ng/pattern/text/text_base.h" 29 #include "core/components_ng/pattern/text/text_menu_extension.h" 30 #include "core/event/ace_events.h" 31 #include "core/event/touch_event.h" 32 33 namespace OHOS::Ace::NG { 34 struct OverlayRequest { 35 bool menuIsShow = true; 36 bool hideHandle = false; 37 bool animation = false; 38 bool hideHandleLine = false; 39 int32_t requestCode = 0; 40 }; 41 42 enum class DragHandleIndex { NONE, FIRST, SECOND }; 43 44 class BaseTextSelectOverlay : public SelectOverlayHolder, public SelectOverlayCallback { 45 DECLARE_ACE_TYPE(BaseTextSelectOverlay, SelectOverlayHolder, SelectOverlayCallback); 46 47 public: BaseTextSelectOverlay(const WeakPtr<TextBase> & textBase)48 explicit BaseTextSelectOverlay(const WeakPtr<TextBase>& textBase) : hostTextBase_(textBase) {} 49 ~BaseTextSelectOverlay() = default; 50 51 static RectF GetVisibleRect(const RefPtr<FrameNode>& node, const RectF& visibleRect); 52 53 template<class T> GetPattern()54 RefPtr<T> GetPattern() const 55 { 56 return DynamicCast<T>(hostTextBase_.Upgrade()); 57 } 58 GetHostTextBase()59 WeakPtr<TextBase> GetHostTextBase() 60 { 61 return hostTextBase_; 62 } 63 64 void ProcessOverlay(const OverlayRequest& request = OverlayRequest()); 65 void ProcessOverlayOnAreaChanged(const OverlayRequest& request = OverlayRequest()); PreProcessOverlay(const OverlayRequest & request)66 virtual bool PreProcessOverlay(const OverlayRequest& request) 67 { 68 return true; 69 } AfterCloseOverlay()70 virtual void AfterCloseOverlay() {} 71 72 // override SelectOverlayHolder 73 RefPtr<FrameNode> GetOwner() override; 74 void OnHandleGlobalTouchEvent(SourceType sourceType, TouchType touchType, bool touchInside = true) override; 75 bool CheckTouchInHostNode(const PointF& touchPoint) override; 76 void OnUpdateSelectOverlayInfo(SelectOverlayInfo& overlayInfo, int32_t requestCode) override; 77 bool CheckRestartHiddenHandleTask(int32_t requestCode) override; 78 std::optional<RectF> GetAncestorNodeViewPort() override; GetCallback()79 RefPtr<SelectOverlayCallback> GetCallback() override 80 { 81 return AceType::Claim(this); 82 } 83 // override SelectOverlayHolder end 84 85 // common method 86 bool SelectOverlayIsOn(); 87 bool SelectOverlayIsCreating(); 88 void CloseOverlay(bool animation, CloseReason reason); 89 void ToggleMenu(); 90 void ShowMenu(); 91 void HideMenu(bool noAnimation = false); 92 void DisableMenu(); 93 void EnableMenu(); 94 virtual void UpdateAllHandlesOffset(); 95 virtual void UpdateFirstHandleOffset(); 96 virtual void UpdateSecondHandleOffset(); 97 void UpdateViewPort(); 98 bool IsShowMouseMenu(); 99 bool IsCurrentMenuVisibile(); 100 bool IsHandleReverse(); 101 void RemoveSelectionHoldCallback(); 102 void SetSelectionHoldCallback(); 103 IsSingleHandle()104 bool IsSingleHandle() 105 { 106 return isSingleHandle_; 107 } 108 IsUsingMouse()109 bool IsUsingMouse() 110 { 111 return isUsingMouse_; 112 } 113 SetIsSingleHandle(bool isSingleHandle)114 void SetIsSingleHandle(bool isSingleHandle) 115 { 116 isSingleHandle_ = isSingleHandle; 117 } 118 SetUsingMouse(bool isUsingMouse)119 void SetUsingMouse(bool isUsingMouse) 120 { 121 isUsingMouse_ = isUsingMouse; 122 } 123 SetShowPaste(bool isShowPaste)124 void SetShowPaste(bool isShowPaste) 125 { 126 isShowPaste_ = isShowPaste; 127 } 128 IsShowPaste()129 bool IsShowPaste() 130 { 131 return isShowPaste_; 132 } 133 SetMenuIsShow(bool isShowMenu)134 void SetMenuIsShow(bool isShowMenu) 135 { 136 isShowMenu_ = isShowMenu; 137 originalMenuIsShow_ = isShowMenu; 138 } 139 IsShowMenu()140 bool IsShowMenu() 141 { 142 return isShowMenu_; 143 } 144 SetIsShowHandleLine(bool isShowHandleLine)145 void SetIsShowHandleLine(bool isShowHandleLine) 146 { 147 isShowHandleLine_ = isShowHandleLine; 148 } 149 SetMouseMenuOffset(const OffsetF & offset)150 void SetMouseMenuOffset(const OffsetF& offset) 151 { 152 mouseMenuOffset_ = offset; 153 } 154 155 // common virtual methods. 156 virtual RectF GetVisibleContentRect(bool isGlobal = false); 157 virtual bool CheckHandleVisible(const RectF& paintRect) = 0; 158 GetPasteMimeTypes()159 virtual std::vector<std::string> GetPasteMimeTypes() 160 { 161 return std::vector<std::string>(); 162 } 163 OnResetTextSelection()164 virtual void OnResetTextSelection() {} 165 166 virtual bool IsAcceptResetSelectionEvent(SourceType sourceType, TouchType touchType); 167 HasRenderTransform()168 bool HasRenderTransform() 169 { 170 UpdateTransformFlag(); 171 return hasTransform_; 172 } 173 // transformed global point to original local point. 174 void RevertLocalPointWithTransform(OffsetF& point); 175 // original local point to transformed global point. 176 void GetGlobalPointsWithTransform(std::vector<OffsetF>& points); 177 // original local rect to transformd global rect. 178 void GetGlobalRectWithTransform(RectF& rect); 179 std::vector<OffsetF> GetGlobalRectVertexWithTransform(const RectF& rect, float extendValue = 0.0f); 180 // original local point to transformed local point. 181 void GetLocalPointsWithTransform(std::vector<OffsetF>& localPoints); 182 void GetLocalPointWithTransform(OffsetF& localPoint); 183 // original local rect to transformed local rect. 184 void GetLocalRectWithTransform(RectF& localRect); 185 186 OffsetF GetPaintOffsetWithoutTransform(); 187 RectF GetPaintRectWithTransform(); 188 OffsetF GetPaintRectOffsetWithTransform(); 189 RectF GetVisibleContentRectWithTransform(float epsilon); 190 bool CheckHandleIsVisibleWithTransform(const OffsetF& startPoint, const OffsetF& endPoint, float epsilon); 191 bool IsPointInRect(const OffsetF& point, const OffsetF& leftBottom, const OffsetF& rightBottom, 192 const OffsetF& rightTop, const OffsetF& leftTop); 193 194 void OnSelectionMenuOptionsUpdate(const NG::OnCreateMenuCallback&& onCreateMenuCallback, 195 const NG::OnMenuItemClickCallback&& onMenuItemClick, const NG::OnPrepareMenuCallback&& onPrepareMenuCallback); 196 OnCreateMenuCallbackUpdate(const NG::OnCreateMenuCallback && onCreateMenuCallback)197 void OnCreateMenuCallbackUpdate(const NG::OnCreateMenuCallback&& onCreateMenuCallback) 198 { 199 onCreateMenuCallback_ = onCreateMenuCallback; 200 } 201 OnMenuItemClickCallbackUpdate(const NG::OnMenuItemClickCallback && onMenuItemClick)202 void OnMenuItemClickCallbackUpdate(const NG::OnMenuItemClickCallback&& onMenuItemClick) 203 { 204 onMenuItemClick_ = onMenuItemClick; 205 } 206 OnPrepareMenuCallbackUpdate(const NG::OnPrepareMenuCallback && onPrepareMenuCallback)207 void OnPrepareMenuCallbackUpdate(const NG::OnPrepareMenuCallback&& onPrepareMenuCallback) 208 { 209 onPrepareMenuCallback_ = onPrepareMenuCallback; 210 } 211 212 float GetHandleDiameter(); 213 VectorF GetHostScale(); 214 void SwitchToOverlayMode(); 215 void SwitchToEmbedMode(); 216 void SetHandleLevelMode(HandleLevelMode mode); IsOverlayMode()217 bool IsOverlayMode() 218 { 219 return handleLevelMode_ == HandleLevelMode::OVERLAY; 220 } 221 OnHandleLevelModeChanged(HandleLevelMode mode)222 void OnHandleLevelModeChanged(HandleLevelMode mode) override 223 { 224 SetHandleLevelMode(mode); 225 UpdateAllHandlesOffset(); 226 UpdateViewPort(); 227 } 228 virtual void OnAncestorNodeChanged(FrameNodeChangeInfoFlag flag); 229 void OnCloseOverlay(OptionMenuType menuType, CloseReason reason, RefPtr<OverlayInfo> info) override; OnHandleMoveStart(const GestureEvent & event,bool isFirst)230 void OnHandleMoveStart(const GestureEvent& event, bool isFirst) override 231 { 232 isHandleDragging_ = true; 233 dragHandleIndex_ = isFirst ? DragHandleIndex::FIRST : DragHandleIndex::SECOND; 234 } OnHandleMoveDone(const RectF & rect,bool isFirst)235 void OnHandleMoveDone(const RectF& rect, bool isFirst) override 236 { 237 isHandleDragging_ = false; 238 dragHandleIndex_ = DragHandleIndex::NONE; 239 } GetIsHandleDragging()240 bool GetIsHandleDragging() 241 { 242 return isHandleDragging_; 243 } 244 bool IsTouchAtHandle(const TouchEventInfo& info); 245 bool IsClickAtHandle(const GestureEvent& info); 246 bool HasUnsupportedTransform(bool checkScale = false); 247 bool CheckUnsupportedTransformMatrix(const RefPtr<RenderContext> context, bool checkScale); 248 bool CheckSwitchToMode(HandleLevelMode mode) override; 249 OnUpdateOnCreateMenuCallback(SelectOverlayInfo & selectInfo)250 void OnUpdateOnCreateMenuCallback(SelectOverlayInfo& selectInfo) 251 { 252 selectInfo.onCreateCallback.onCreateMenuCallback = onCreateMenuCallback_; 253 selectInfo.onCreateCallback.onMenuItemClick = onMenuItemClick_; 254 selectInfo.onCreateCallback.onPrepareMenuCallback = onPrepareMenuCallback_; 255 auto textRange = [weak = GetHostTextBase()](int32_t& start, int32_t& end) { 256 auto pattern = weak.Upgrade(); 257 CHECK_NULL_VOID(pattern); 258 pattern->GetSelectIndex(start, end); 259 }; 260 selectInfo.onCreateCallback.textRangeCallback = textRange; 261 if (onPrepareMenuCallback_) { 262 auto beforeOnPrepareMenu = [weak = WeakClaim(this)]() { 263 auto overlay = weak.Upgrade(); 264 CHECK_NULL_VOID(overlay); 265 overlay->BeforeOnPrepareMenu(); 266 }; 267 selectInfo.onCreateCallback.beforeOnPrepareMenuCallback = beforeOnPrepareMenu; 268 } else { 269 selectInfo.onCreateCallback.beforeOnPrepareMenuCallback = nullptr; 270 } 271 } 272 bool GetClipHandleViewPort(RectF& rect); 273 bool CalculateClippedRect(RectF& rect); 274 void MarkOverlayDirty(); 275 void OnHandleMarkInfoChange(const std::shared_ptr<SelectOverlayInfo> info, SelectOverlayDirtyFlag flag) override; 276 void UpdateHandleColor(); GetHandleColor()277 virtual std::optional<Color> GetHandleColor() 278 { 279 return std::nullopt; 280 } 281 void AddAvoidKeyboardCallback(bool isCustomKeyboard); 282 void RemoveAvoidKeyboardCallback(); 283 IsEnableContainerModal()284 bool IsEnableContainerModal() override 285 { 286 return enableContainerModal_; 287 } 288 bool IsHiddenHandle(); 289 290 bool IsHandleVisible(bool isFirst); SetMenuTranslateIsSupport(bool menuTranslateIsSupport)291 void SetMenuTranslateIsSupport(bool menuTranslateIsSupport) 292 { 293 menuTranslateIsSupport_ = menuTranslateIsSupport; 294 } SetIsSupportMenuSearch(bool isSupportMenuSearch)295 void SetIsSupportMenuSearch(bool isSupportMenuSearch) 296 { 297 isSupportMenuSearch_ = isSupportMenuSearch; 298 } SetEnableSubWindowMenu(bool enableSubWindowMenu)299 void SetEnableSubWindowMenu(bool enableSubWindowMenu) 300 { 301 enableSubWindowMenu_ = enableSubWindowMenu; 302 } 303 void UpdateMenuOnWindowSizeChanged(WindowSizeChangeReason type); 304 GetIsHostNodeEnableSubWindowMenu()305 bool GetIsHostNodeEnableSubWindowMenu() const override 306 { 307 return isHostNodeEnableSubWindowMenu_; 308 } 309 SetIsHostNodeEnableSubWindowMenu(bool enable)310 void SetIsHostNodeEnableSubWindowMenu(bool enable) 311 { 312 isHostNodeEnableSubWindowMenu_ = enable; 313 } 314 GetSelectOverlayInfos()315 std::optional<SelectOverlayInfo> GetSelectOverlayInfos() 316 { 317 auto manager = GetManager<SelectContentOverlayManager>(); 318 CHECK_NULL_RETURN(manager, std::optional<SelectOverlayInfo>()); 319 return manager->GetSelectOverlayInfo(); 320 } BeforeOnPrepareMenu()321 virtual void BeforeOnPrepareMenu() {} ChangeSecondHandleHeight(const GestureEvent & event,bool isOverlayMode)322 virtual bool ChangeSecondHandleHeight(const GestureEvent& event, bool isOverlayMode) 323 { 324 return false; 325 } 326 bool GetDragViewHandleRects(RectF& firstRect, RectF& secondRect); 327 void UpdateIsSingleHandle(bool isSingleHandle); 328 329 protected: 330 RectF MergeSelectedBoxes( 331 const std::vector<RectF>& boxes, const RectF& contentRect, const RectF& textRect, const OffsetF& paintOffset); IsMouseClickDown(SourceType sourceType,TouchType touchType)332 bool IsMouseClickDown(SourceType sourceType, TouchType touchType) 333 { 334 return sourceType == SourceType::MOUSE && touchType == TouchType::DOWN; 335 } 336 IsTouchUp(SourceType sourceType,TouchType touchType)337 bool IsTouchUp(SourceType sourceType, TouchType touchType) 338 { 339 return (sourceType == SourceType::TOUCH || sourceType == SourceType::TOUCH_PAD) && touchType == TouchType::UP; 340 } 341 342 RectF ConvertPaintInfoToRect(const SelectHandlePaintInfo& paintInfo); 343 void SetTransformPaintInfo(SelectHandleInfo& handleInfo, const RectF& localHandleRect); 344 bool CheckHandleCanPaintInHost(const RectF& firstRect, const RectF& secondRect); 345 virtual RectF GetHandleLocalPaintRect(DragHandleIndex dragHandleIndex); 346 virtual void CalcHandleLevelMode(const RectF& firstLocalPaintRect, const RectF& secondLocalPaintRect); 347 bool IsAncestorNodeStartAnimation(FrameNodeChangeInfoFlag flag); 348 bool IsAncestorNodeGeometryChange(FrameNodeChangeInfoFlag flag); 349 bool IsAncestorNodeStartScroll(FrameNodeChangeInfoFlag flag); 350 bool IsAncestorNodeEndScroll(FrameNodeChangeInfoFlag flag); 351 bool IsAncestorNodeTransformChange(FrameNodeChangeInfoFlag flag); 352 bool IsAncestorNodeHasTransition(FrameNodeChangeInfoFlag flag); SetEnableHandleLevel(bool enableHandleLevel)353 void SetEnableHandleLevel(bool enableHandleLevel) 354 { 355 enableHandleLevel_ = enableHandleLevel; 356 } 357 void RegisterScrollingListener(const RefPtr<FrameNode> scrollableNode); 358 void OnHandleScrolling(const WeakPtr<FrameNode>& scrollingNode); 359 virtual void UpdateTransformFlag(); 360 bool CheckHasTransformAttr(); UpdateOriginalMenuIsShow()361 void UpdateOriginalMenuIsShow() 362 { 363 originalMenuIsShow_ = IsCurrentMenuVisibile(); 364 } 365 virtual void UpdateMenuWhileAncestorNodeChanged( 366 bool shouldHideMenu, bool shouldShowMenu, FrameNodeChangeInfoFlag extraFlag); UpdateClipHandleViewPort(RectF & rect)367 virtual void UpdateClipHandleViewPort(RectF& rect) {}; 368 static bool GetFrameNodeContentRect(const RefPtr<FrameNode>& node, RectF& rect); 369 static bool GetScrollableClipContentRect(const RefPtr<FrameNode>& node, RectF& rect); 370 static std::pair<ContentClipMode, std::optional<ContentClip>> GetScrollableClipInfo(const RefPtr<FrameNode>& node); IsClipHandleWithViewPort()371 virtual bool IsClipHandleWithViewPort() 372 { 373 return false; 374 } 375 void ApplySelectAreaWithKeyboard(RectF& selectArea); 376 bool IsHandleInParentSafeAreaPadding(); 377 bool IsHandleInParentSafeAreaPadding(const RectF& firstRect, const RectF& secondRect); 378 bool CheckHandleIsInSafeAreaPadding(const RefPtr<FrameNode>& node, const RectF& handle); CheckEnableContainerModal()379 void CheckEnableContainerModal() 380 { 381 enableContainerModal_ = true; 382 } 383 bool IsNeedMenuTranslate(); 384 void HandleOnTranslate(); 385 bool IsNeedMenuSearch(); 386 void HandleOnSearch(); AllowTranslate()387 virtual bool AllowTranslate() 388 { 389 return false; 390 } AllowSearch()391 virtual bool AllowSearch() 392 { 393 return false; 394 } 395 bool IsSupportMenuShare(); 396 bool IsNeedMenuShare(); 397 void HandleOnShare(); AllowShare()398 virtual bool AllowShare() 399 { 400 return false; 401 } 402 std::optional<OverlayRequest> latestReqeust_; 403 bool hasTransform_ = false; 404 HandleLevelMode handleLevelMode_ = HandleLevelMode::OVERLAY; 405 OnCreateMenuCallback onCreateMenuCallback_; 406 OnMenuItemClickCallback onMenuItemClick_; 407 OnPrepareMenuCallback onPrepareMenuCallback_; 408 bool isHandleMoving_ = false; 409 DragHandleIndex dragHandleIndex_ = DragHandleIndex::NONE; 410 RectF ConvertWindowToScreenDomain(RectF rect); 411 EdgeF ConvertWindowToScreenDomain(EdgeF edge); 412 std::string GetTranslateParamRectStr(RectF rect, EdgeF rectLeftTop, EdgeF rectRightBottom); 413 414 private: 415 void FindScrollableParentAndSetCallback(const RefPtr<FrameNode>& host); 416 void RegisterParentScrollCallback(const RefPtr<FrameNode>& host, int32_t parentId); 417 void ShowSelectOverlay(const OverlayRequest& request, bool hasClipboardData); 418 void GetHandlePoints(const RectF& handleRect, std::vector<PointF>& points, bool handleOnTop); 419 bool IsPointsInRegion(const std::vector<PointF>& points, const RectF& regionRect); 420 bool CheckAndUpdateHostGlobalPaintRect(); 421 bool CheckHasTransformMatrix(const RefPtr<RenderContext>& context); 422 bool IsEnableSelectionMenu(); 423 bool NeedsProcessMenuOnWinChange(); 424 bool isHandleDragging_ = false; 425 bool isSingleHandle_ = false; 426 bool isShowPaste_ = false; 427 bool isShowMenu_ = true; 428 bool isShowHandleLine_ = true; 429 bool isUsingMouse_ = false; 430 OffsetF mouseMenuOffset_; 431 WeakPtr<TextBase> hostTextBase_; 432 bool enableHandleLevel_ = false; 433 bool touchAtHandle_ = false; 434 bool isChangeToOverlayModeAtEdge_ = true; 435 bool hasRegisterListener_ = false; 436 RectF globalPaintRect_; 437 bool originalMenuIsShow_ = true; 438 bool enableContainerModal_ = false; 439 bool menuTranslateIsSupport_ = false; 440 bool isSupportMenuSearch_ = false; 441 bool enableSubWindowMenu_ = false; 442 /** 443 * Whether the host node supports show menu in subwindow. 444 * In certain scenarios, such as the autofill scenario: 445 * the menu window may conflict with the autofill window. 446 */ 447 bool isHostNodeEnableSubWindowMenu_ = true; 448 bool isSuperFoldDisplayDevice_ = false; 449 }; 450 451 } // namespace OHOS::Ace::NG 452 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_TEXT_TEXT_BASE_SELECT_OVERLAY_H 453