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( 195 const NG::OnCreateMenuCallback&& onCreateMenuCallback, const NG::OnMenuItemClickCallback&& onMenuItemClick); 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 207 float GetHandleDiameter(); 208 VectorF GetHostScale(); 209 void SwitchToOverlayMode(); 210 void SwitchToEmbedMode(); 211 void SetHandleLevelMode(HandleLevelMode mode); IsOverlayMode()212 bool IsOverlayMode() 213 { 214 return handleLevelMode_ == HandleLevelMode::OVERLAY; 215 } 216 OnHandleLevelModeChanged(HandleLevelMode mode)217 void OnHandleLevelModeChanged(HandleLevelMode mode) override 218 { 219 SetHandleLevelMode(mode); 220 UpdateAllHandlesOffset(); 221 UpdateViewPort(); 222 } 223 virtual void OnAncestorNodeChanged(FrameNodeChangeInfoFlag flag); 224 void OnCloseOverlay(OptionMenuType menuType, CloseReason reason, RefPtr<OverlayInfo> info) override; OnHandleMoveStart(const GestureEvent & event,bool isFirst)225 void OnHandleMoveStart(const GestureEvent& event, bool isFirst) override 226 { 227 isHandleDragging_ = true; 228 dragHandleIndex_ = isFirst ? DragHandleIndex::FIRST : DragHandleIndex::SECOND; 229 } OnHandleMoveDone(const RectF & rect,bool isFirst)230 void OnHandleMoveDone(const RectF& rect, bool isFirst) override 231 { 232 isHandleDragging_ = false; 233 dragHandleIndex_ = DragHandleIndex::NONE; 234 } GetIsHandleDragging()235 bool GetIsHandleDragging() 236 { 237 return isHandleDragging_; 238 } 239 bool IsTouchAtHandle(const TouchEventInfo& info); 240 bool IsClickAtHandle(const GestureEvent& info); 241 bool HasUnsupportedTransform(bool checkScale = false); 242 bool CheckUnsupportedTransformMatrix(const RefPtr<RenderContext> context, bool checkScale); 243 bool CheckSwitchToMode(HandleLevelMode mode) override; 244 OnUpdateOnCreateMenuCallback(SelectOverlayInfo & selectInfo)245 void OnUpdateOnCreateMenuCallback(SelectOverlayInfo& selectInfo) 246 { 247 selectInfo.onCreateCallback.onCreateMenuCallback = onCreateMenuCallback_; 248 selectInfo.onCreateCallback.onMenuItemClick = onMenuItemClick_; 249 auto textRange = [weak = GetHostTextBase()](int32_t& start, int32_t& end) { 250 auto pattern = weak.Upgrade(); 251 CHECK_NULL_VOID(pattern); 252 pattern->GetSelectIndex(start, end); 253 }; 254 selectInfo.onCreateCallback.textRangeCallback = textRange; 255 } 256 bool GetClipHandleViewPort(RectF& rect); 257 bool CalculateClippedRect(RectF& rect); 258 void MarkOverlayDirty(); 259 void OnHandleMarkInfoChange(const std::shared_ptr<SelectOverlayInfo> info, SelectOverlayDirtyFlag flag) override; 260 void UpdateHandleColor(); GetHandleColor()261 virtual std::optional<Color> GetHandleColor() 262 { 263 return std::nullopt; 264 } 265 void AddAvoidKeyboardCallback(bool isCustomKeyboard); 266 void RemoveAvoidKeyboardCallback(); 267 IsEnableContainerModal()268 bool IsEnableContainerModal() override 269 { 270 return enableContainerModal_; 271 } 272 bool IsHiddenHandle(); 273 274 bool IsHandleVisible(bool isFirst); SetMenuTranslateIsSupport(bool menuTranslateIsSupport)275 void SetMenuTranslateIsSupport(bool menuTranslateIsSupport) 276 { 277 menuTranslateIsSupport_ = menuTranslateIsSupport; 278 } SetIsSupportMenuSearch(bool isSupportMenuSearch)279 void SetIsSupportMenuSearch(bool isSupportMenuSearch) 280 { 281 isSupportMenuSearch_ = isSupportMenuSearch; 282 } SetEnableSubWindowMenu(bool enableSubWindowMenu)283 void SetEnableSubWindowMenu(bool enableSubWindowMenu) 284 { 285 enableSubWindowMenu_ = enableSubWindowMenu; 286 } 287 void UpdateMenuOnWindowSizeChanged(WindowSizeChangeReason type); 288 GetIsHostNodeEnableSubWindowMenu()289 bool GetIsHostNodeEnableSubWindowMenu() const override 290 { 291 return isHostNodeEnableSubWindowMenu_; 292 } 293 SetIsHostNodeEnableSubWindowMenu(bool enable)294 void SetIsHostNodeEnableSubWindowMenu(bool enable) 295 { 296 isHostNodeEnableSubWindowMenu_ = enable; 297 } 298 GetSelectOverlayInfos()299 std::optional<SelectOverlayInfo> GetSelectOverlayInfos() 300 { 301 auto manager = GetManager<SelectContentOverlayManager>(); 302 CHECK_NULL_RETURN(manager, std::optional<SelectOverlayInfo>()); 303 return manager->GetSelectOverlayInfo(); 304 } 305 306 protected: 307 RectF MergeSelectedBoxes( 308 const std::vector<RectF>& boxes, const RectF& contentRect, const RectF& textRect, const OffsetF& paintOffset); IsMouseClickDown(SourceType sourceType,TouchType touchType)309 bool IsMouseClickDown(SourceType sourceType, TouchType touchType) 310 { 311 return sourceType == SourceType::MOUSE && touchType == TouchType::DOWN; 312 } 313 IsTouchUp(SourceType sourceType,TouchType touchType)314 bool IsTouchUp(SourceType sourceType, TouchType touchType) 315 { 316 return (sourceType == SourceType::TOUCH || sourceType == SourceType::TOUCH_PAD) && touchType == TouchType::UP; 317 } 318 319 RectF ConvertPaintInfoToRect(const SelectHandlePaintInfo& paintInfo); 320 void SetTransformPaintInfo(SelectHandleInfo& handleInfo, const RectF& localHandleRect); 321 bool CheckHandleCanPaintInHost(const RectF& firstRect, const RectF& secondRect); 322 virtual RectF GetHandleLocalPaintRect(DragHandleIndex dragHandleIndex); 323 virtual void CalcHandleLevelMode(const RectF& firstLocalPaintRect, const RectF& secondLocalPaintRect); 324 bool IsAncestorNodeStartAnimation(FrameNodeChangeInfoFlag flag); 325 bool IsAncestorNodeGeometryChange(FrameNodeChangeInfoFlag flag); 326 bool IsAncestorNodeStartScroll(FrameNodeChangeInfoFlag flag); 327 bool IsAncestorNodeEndScroll(FrameNodeChangeInfoFlag flag); 328 bool IsAncestorNodeTransformChange(FrameNodeChangeInfoFlag flag); 329 bool IsAncestorNodeHasTransition(FrameNodeChangeInfoFlag flag); SetEnableHandleLevel(bool enableHandleLevel)330 void SetEnableHandleLevel(bool enableHandleLevel) 331 { 332 enableHandleLevel_ = enableHandleLevel; 333 } 334 void RegisterScrollingListener(const RefPtr<FrameNode> scrollableNode); 335 void OnHandleScrolling(const WeakPtr<FrameNode>& scrollingNode); 336 virtual void UpdateTransformFlag(); 337 bool CheckHasTransformAttr(); UpdateOriginalMenuIsShow()338 void UpdateOriginalMenuIsShow() 339 { 340 originalMenuIsShow_ = IsCurrentMenuVisibile(); 341 } 342 virtual void UpdateMenuWhileAncestorNodeChanged( 343 bool shouldHideMenu, bool shouldShowMenu, FrameNodeChangeInfoFlag extraFlag); UpdateClipHandleViewPort(RectF & rect)344 virtual void UpdateClipHandleViewPort(RectF& rect) {}; 345 static bool GetFrameNodeContentRect(const RefPtr<FrameNode>& node, RectF& rect); 346 static bool GetScrollableClipContentRect(const RefPtr<FrameNode>& node, RectF& rect); 347 static std::pair<ContentClipMode, std::optional<ContentClip>> GetScrollableClipInfo(const RefPtr<FrameNode>& node); IsClipHandleWithViewPort()348 virtual bool IsClipHandleWithViewPort() 349 { 350 return false; 351 } 352 void ApplySelectAreaWithKeyboard(RectF& selectArea); 353 bool IsHandleInParentSafeAreaPadding(); 354 bool IsHandleInParentSafeAreaPadding(const RectF& firstRect, const RectF& secondRect); 355 bool CheckHandleIsInSafeAreaPadding(const RefPtr<FrameNode>& node, const RectF& handle); CheckEnableContainerModal()356 void CheckEnableContainerModal() 357 { 358 enableContainerModal_ = true; 359 } 360 bool IsNeedMenuTranslate(); 361 void HandleOnTranslate(); 362 bool IsNeedMenuSearch(); 363 void HandleOnSearch(); AllowTranslate()364 virtual bool AllowTranslate() 365 { 366 return false; 367 } AllowSearch()368 virtual bool AllowSearch() 369 { 370 return false; 371 } 372 bool IsSupportMenuShare(); 373 bool IsNeedMenuShare(); 374 void HandleOnShare(); AllowShare()375 virtual bool AllowShare() 376 { 377 return false; 378 } 379 std::optional<OverlayRequest> latestReqeust_; 380 bool hasTransform_ = false; 381 HandleLevelMode handleLevelMode_ = HandleLevelMode::OVERLAY; 382 OnCreateMenuCallback onCreateMenuCallback_; 383 OnMenuItemClickCallback onMenuItemClick_; 384 bool isHandleMoving_ = false; 385 DragHandleIndex dragHandleIndex_ = DragHandleIndex::NONE; 386 RectF ConvertWindowToScreenDomain(RectF rect); 387 EdgeF ConvertWindowToScreenDomain(EdgeF edge); 388 std::string GetTranslateParamRectStr(RectF rect, EdgeF rectLeftTop, EdgeF rectRightBottom); 389 390 private: 391 void FindScrollableParentAndSetCallback(const RefPtr<FrameNode>& host); 392 void RegisterParentScrollCallback(const RefPtr<FrameNode>& host, int32_t parentId); 393 void ShowSelectOverlay(const OverlayRequest& request, bool hasClipboardData); 394 void GetHandlePoints(const RectF& handleRect, std::vector<PointF>& points, bool handleOnTop); 395 bool IsPointsInRegion(const std::vector<PointF>& points, const RectF& regionRect); 396 bool CheckAndUpdateHostGlobalPaintRect(); 397 bool CheckHasTransformMatrix(const RefPtr<RenderContext>& context); 398 bool IsEnableSelectionMenu(); 399 bool NeedsProcessMenuOnWinChange(); 400 bool isHandleDragging_ = false; 401 bool isSingleHandle_ = false; 402 bool isShowPaste_ = false; 403 bool isShowMenu_ = true; 404 bool isShowHandleLine_ = true; 405 bool isUsingMouse_ = false; 406 OffsetF mouseMenuOffset_; 407 WeakPtr<TextBase> hostTextBase_; 408 bool enableHandleLevel_ = false; 409 bool touchAtHandle_ = false; 410 bool isChangeToOverlayModeAtEdge_ = true; 411 bool hasRegisterListener_ = false; 412 RectF globalPaintRect_; 413 bool originalMenuIsShow_ = true; 414 bool enableContainerModal_ = false; 415 bool menuTranslateIsSupport_ = false; 416 bool isSupportMenuSearch_ = false; 417 bool enableSubWindowMenu_ = false; 418 /** 419 * Whether the host node supports show menu in subwindow. 420 * In certain scenarios, such as the autofill scenario: 421 * the menu window may conflict with the autofill window. 422 */ 423 bool isHostNodeEnableSubWindowMenu_ = true; 424 bool isSuperFoldDisplayDevice_ = false; 425 }; 426 427 } // namespace OHOS::Ace::NG 428 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_TEXT_TEXT_BASE_SELECT_OVERLAY_H 429