• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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