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 #include "core/components_ng/manager/select_content_overlay/select_content_overlay_manager.h"
17 
18 #include <optional>
19 #include <utility>
20 
21 #include "base/memory/ace_type.h"
22 #include "base/memory/referenced.h"
23 #include "base/utils/utils.h"
24 #include "core/common/container.h"
25 #include "core/components_ng/pattern/select_content_overlay/select_content_overlay_pattern.h"
26 #include "core/components_ng/pattern/select_overlay/select_overlay_node.h"
27 #include "core/components_ng/pattern/select_overlay/select_overlay_property.h"
28 #include "core/event/touch_event.h"
29 #include "core/pipeline_ng/pipeline_context.h"
30 
31 namespace OHOS::Ace::NG {
32 namespace {
GetSelectOverlayPattern(const WeakPtr<FrameNode> & overlayNode)33 RefPtr<SelectContentOverlayPattern> GetSelectOverlayPattern(const WeakPtr<FrameNode>& overlayNode)
34 {
35     auto node = overlayNode.Upgrade();
36     CHECK_NULL_RETURN(node, nullptr);
37     auto selectOverlayNode = AceType::DynamicCast<SelectOverlayNode>(node);
38     CHECK_NULL_RETURN(selectOverlayNode, nullptr);
39     return selectOverlayNode->GetPattern<SelectContentOverlayPattern>();
40 }
41 
GetSelectMenuPattern(const WeakPtr<SelectContentOverlayManager> & manager)42 RefPtr<SelectContentOverlayPattern> GetSelectMenuPattern(const WeakPtr<SelectContentOverlayManager>& manager)
43 {
44     auto overlayManager = manager.Upgrade();
45     CHECK_NULL_RETURN(overlayManager, nullptr);
46     auto pattern = overlayManager->GetMenuPattern();
47     return AceType::DynamicCast<SelectContentOverlayPattern>(pattern);
48 }
49 
GetSelectHandlePattern(const WeakPtr<SelectContentOverlayManager> & manager)50 RefPtr<SelectContentOverlayPattern> GetSelectHandlePattern(const WeakPtr<SelectContentOverlayManager>& manager)
51 {
52     auto overlayManager = manager.Upgrade();
53     CHECK_NULL_RETURN(overlayManager, nullptr);
54     auto pattern = overlayManager->GetHandlePattern();
55     return AceType::DynamicCast<SelectContentOverlayPattern>(pattern);
56 }
57 } // namespace
58 
GetOverlayManager(const RefPtr<SelectOverlayHolder> & holder)59 const RefPtr<SelectContentOverlayManager> SelectContentOverlayManager::GetOverlayManager(
60     const RefPtr<SelectOverlayHolder>& holder)
61 {
62     auto pipeline = PipelineContext::GetCurrentContextSafely();
63     CHECK_NULL_RETURN(pipeline, nullptr);
64     auto overlayManager = pipeline->GetSelectOverlayManager();
65     CHECK_NULL_RETURN(overlayManager, nullptr);
66     auto contentManager = overlayManager->GetSelectContentOverlayManager();
67     if (!holder) {
68         return contentManager;
69     }
70     if (!contentManager->HasHolder(holder->GetOwnerId())) {
71         contentManager->SetHolder(holder);
72     }
73     return contentManager;
74 }
75 
SetHolder(const RefPtr<SelectOverlayHolder> & holder)76 void SelectContentOverlayManager::SetHolder(const RefPtr<SelectOverlayHolder>& holder)
77 {
78     CHECK_NULL_VOID(holder);
79     if (!selectOverlayHolder_) {
80         SetHolderInternal(holder);
81         return;
82     }
83     auto prevOwnerId = selectOverlayHolder_->GetOwnerId();
84     auto ownerId = holder->GetOwnerId();
85     if (selectionHoldId_ > 0 && ownerId != selectionHoldId_) {
86         ResetSelectionRect();
87         if (legacyManagerCallbacks_.selectionResetCallback) {
88             legacyManagerCallbacks_.selectionResetCallback();
89         }
90     }
91     if (prevOwnerId == ownerId) {
92         return;
93     }
94     CloseInternal(prevOwnerId, false, CloseReason::CLOSE_REASON_HOLD_BY_OTHER);
95     SetHolderInternal(holder);
96 }
97 
SetHolderInternal(const RefPtr<SelectOverlayHolder> & holder)98 void SelectContentOverlayManager::SetHolderInternal(const RefPtr<SelectOverlayHolder>& holder)
99 {
100     // unbind old holder
101     if (selectOverlayHolder_) {
102         selectOverlayHolder_->OnBind(nullptr);
103     }
104     selectOverlayHolder_ = holder;
105     // bind new holder
106     if (selectOverlayHolder_) {
107         selectOverlayHolder_->OnBind(WeakClaim(this));
108     }
109 }
HasHolder(int32_t id)110 bool SelectContentOverlayManager::HasHolder(int32_t id)
111 {
112     CHECK_NULL_RETURN(selectOverlayHolder_, false);
113     return selectOverlayHolder_->GetOwnerId() == id;
114 }
115 
Show(bool animation,int32_t requestCode)116 void SelectContentOverlayManager::Show(bool animation, int32_t requestCode)
117 {
118     CHECK_NULL_VOID(selectOverlayHolder_);
119     auto info = BuildSelectOverlayInfo(requestCode);
120     if (!info.menuInfo.menuIsShow && info.isUsingMouse) {
121         return;
122     }
123     if (legacyManagerCallbacks_.closeCallback) {
124         legacyManagerCallbacks_.closeCallback(false, true);
125     }
126     info.enableHandleLevel = info.enableHandleLevel && !info.isUsingMouse;
127     if (IsOpen()) {
128         if (info.recreateOverlay || info.menuInfo.menuType != shareOverlayInfo_->menuInfo.menuType) {
129             auto holder = selectOverlayHolder_;
130             CloseInternal(selectOverlayHolder_->GetOwnerId(), false, CloseReason::CLOSE_REASON_BY_RECREATE);
131             SetHolder(holder);
132             CreateSelectOverlay(info, animation);
133             return;
134         }
135         UpdateExistOverlay(info, animation, requestCode);
136     } else {
137         CreateSelectOverlay(info, animation);
138     }
139 }
140 
BuildSelectOverlayInfo(int32_t requestCode)141 SelectOverlayInfo SelectContentOverlayManager::BuildSelectOverlayInfo(int32_t requestCode)
142 {
143     SelectOverlayInfo overlayInfo;
144     UpdateStatusInfos(overlayInfo);
145     overlayInfo.menuCallback.onCopy = MakeMenuCallback(OptionMenuActionId::COPY, overlayInfo);
146     overlayInfo.menuCallback.onPaste = MakeMenuCallback(OptionMenuActionId::PASTE, overlayInfo);
147     overlayInfo.menuCallback.onCut = MakeMenuCallback(OptionMenuActionId::CUT, overlayInfo);
148     overlayInfo.menuCallback.onSelectAll = MakeMenuCallback(OptionMenuActionId::SELECT_ALL, overlayInfo);
149     overlayInfo.menuCallback.onCameraInput = MakeMenuCallback(OptionMenuActionId::CAMERA_INPUT, overlayInfo);
150     overlayInfo.menuCallback.onAIWrite = MakeMenuCallback(OptionMenuActionId::AI_WRITE, overlayInfo);
151     overlayInfo.menuCallback.onAppear = MakeMenuCallback(OptionMenuActionId::APPEAR, overlayInfo);
152     overlayInfo.menuCallback.onDisappear = MakeMenuCallback(OptionMenuActionId::DISAPPEAR, overlayInfo);
153     overlayInfo.isUseOverlayNG = true;
154     RegisterTouchCallback(overlayInfo);
155     RegisterHandleCallback(overlayInfo);
156     selectOverlayHolder_->OnUpdateSelectOverlayInfo(overlayInfo, requestCode);
157     return overlayInfo;
158 }
159 
UpdateStatusInfos(SelectOverlayInfo & overlayInfo)160 void SelectContentOverlayManager::UpdateStatusInfos(SelectOverlayInfo& overlayInfo)
161 {
162     auto firstHandle = selectOverlayHolder_->GetFirstHandleInfo();
163     auto secondHandle = selectOverlayHolder_->GetSecondHandleInfo();
164     if (firstHandle.has_value()) {
165         overlayInfo.firstHandle = firstHandle.value();
166     } else {
167         overlayInfo.firstHandle.isShow = false;
168     }
169     if (secondHandle.has_value()) {
170         overlayInfo.secondHandle = secondHandle.value();
171     } else {
172         overlayInfo.secondHandle.isShow = false;
173     }
174     SelectMenuInfo menuInfo;
175     selectOverlayHolder_->OnUpdateMenuInfo(menuInfo, DIRTY_ALL_MENU_ITEM);
176     overlayInfo.menuInfo = menuInfo;
177     overlayInfo.callerFrameNode = selectOverlayHolder_->GetOwner();
178     overlayInfo.selectText = selectOverlayHolder_->GetSelectedText();
179     overlayInfo.selectArea = selectOverlayHolder_->GetSelectArea();
180 }
181 
RegisterHandleCallback(SelectOverlayInfo & info)182 void SelectContentOverlayManager::RegisterHandleCallback(SelectOverlayInfo& info)
183 {
184     CHECK_NULL_VOID(selectOverlayHolder_);
185     auto callback = selectOverlayHolder_->GetCallback();
186     CHECK_NULL_VOID(callback);
187     if (!callback->IsRegisterHandleCallback()) {
188         return;
189     }
190     info.onHandleMoveStart =
191         [weakCallback = WeakClaim(AceType::RawPtr(callback))](const GestureEvent& event, bool isFirst) {
192             auto overlayCallback = weakCallback.Upgrade();
193             CHECK_NULL_VOID(overlayCallback);
194             overlayCallback->OnHandleMoveStart(event, isFirst);
195         };
196     info.onHandleMove = [weakCallback = WeakClaim(AceType::RawPtr(callback))](const RectF& rect, bool isFirst) {
197         auto overlayCallback = weakCallback.Upgrade();
198         CHECK_NULL_VOID(overlayCallback);
199         overlayCallback->OnHandleMove(rect, isFirst);
200     };
201     info.onHandleMoveDone = [weakCallback = WeakClaim(AceType::RawPtr(callback))](const RectF& rect, bool isFirst) {
202         auto overlayCallback = weakCallback.Upgrade();
203         CHECK_NULL_VOID(overlayCallback);
204         overlayCallback->OnHandleMoveDone(rect, isFirst);
205     };
206     info.onHandleReverse = [weakCallback = WeakClaim(AceType::RawPtr(callback))](bool isReverse) {
207         auto overlayCallback = weakCallback.Upgrade();
208         CHECK_NULL_VOID(overlayCallback);
209         overlayCallback->OnHandleReverse(isReverse);
210     };
211     info.onHandleIsHidden = [weakCallback = WeakClaim(AceType::RawPtr(callback))]() {
212         auto overlayCallback = weakCallback.Upgrade();
213         CHECK_NULL_VOID(overlayCallback);
214         overlayCallback->OnHandleIsHidden();
215     };
216 }
217 
RegisterTouchCallback(SelectOverlayInfo & info)218 void SelectContentOverlayManager::RegisterTouchCallback(SelectOverlayInfo& info)
219 {
220     CHECK_NULL_VOID(selectOverlayHolder_);
221     auto callback = selectOverlayHolder_->GetCallback();
222     CHECK_NULL_VOID(callback);
223     if (!callback->IsRegisterTouchCallback()) {
224         return;
225     }
226     info.onTouchDown = [weakCallback = WeakClaim(AceType::RawPtr(callback))](const TouchEventInfo& event) {
227         auto callback = weakCallback.Upgrade();
228         CHECK_NULL_VOID(callback);
229         callback->OnOverlayTouchDown(event);
230     };
231     info.onTouchUp = [weakCallback = WeakClaim(AceType::RawPtr(callback))](const TouchEventInfo& event) {
232         auto callback = weakCallback.Upgrade();
233         CHECK_NULL_VOID(callback);
234         callback->OnOverlayTouchUp(event);
235     };
236     info.onTouchMove = [weakCallback = WeakClaim(AceType::RawPtr(callback))](const TouchEventInfo& event) {
237         auto callback = weakCallback.Upgrade();
238         CHECK_NULL_VOID(callback);
239         callback->OnOverlayTouchMove(event);
240     };
241     info.onClick = [weakCallback = WeakClaim(AceType::RawPtr(callback))](const GestureEvent& event, bool isClickCaret) {
242         auto callback = weakCallback.Upgrade();
243         CHECK_NULL_VOID(callback);
244         callback->OnOverlayClick(event, isClickCaret);
245     };
246     info.onMouseEvent = [weakCallback = WeakClaim(AceType::RawPtr(callback))](const MouseInfo& event) {
247         auto callback = weakCallback.Upgrade();
248         CHECK_NULL_VOID(callback);
249         callback->OnHandleMouseEvent(event);
250     };
251 }
252 
MakeMenuCallback(OptionMenuActionId id,const SelectOverlayInfo & info)253 std::function<void()> SelectContentOverlayManager::MakeMenuCallback(
254     OptionMenuActionId id, const SelectOverlayInfo& info)
255 {
256     auto callback = selectOverlayHolder_->GetCallback();
257     CHECK_NULL_RETURN(callback, nullptr);
258     return [actionId = id, weakCallback = WeakClaim(AceType::RawPtr(callback)), menuType = info.menuInfo.menuType]() {
259         auto callback = weakCallback.Upgrade();
260         CHECK_NULL_VOID(callback);
261         callback->OnMenuItemAction(actionId, menuType);
262     };
263 }
264 
UpdateExistOverlay(const SelectOverlayInfo & info,bool animation,int32_t requestCode)265 void SelectContentOverlayManager::UpdateExistOverlay(const SelectOverlayInfo& info, bool animation, int32_t requestCode)
266 {
267     // update menu node
268     auto menuPattern = GetSelectMenuPattern(WeakClaim(this));
269     if (menuPattern) {
270         if (!info.isSingleHandle) {
271             menuPattern->UpdateSelectArea(info.selectArea);
272             menuPattern->SetSelectInfo(info.selectText);
273         }
274         menuPattern->UpdateMenuInfo(info.menuInfo);
275         menuPattern->UpdateViewPort(info.ancestorViewPort);
276     }
277     // update handle node
278     auto handlePattern = GetSelectHandlePattern(WeakClaim(this));
279     if (handlePattern) {
280         handlePattern->UpdateIsSingleHandle(info.isSingleHandle);
281         handlePattern->UpdateIsShowHandleLine(info.isHandleLineShow);
282         handlePattern->UpdateFirstAndSecondHandleInfo(info.firstHandle, info.secondHandle);
283         TAG_LOGI(AceLogTag::ACE_SELECT_OVERLAY,
284             "Update first %{public}s isShow %{public}d, second %{public}s isShow %{public}d",
285             info.firstHandle.paintRect.ToString().c_str(), info.firstHandle.isShow,
286             info.secondHandle.paintRect.ToString().c_str(), info.secondHandle.isShow);
287         if (info.isSingleHandle) {
288             if (selectOverlayHolder_->CheckRestartHiddenHandleTask(requestCode)) {
289                 handlePattern->RestartHiddenHandleTask(true);
290             }
291         } else {
292             handlePattern->CancelHiddenHandleTask();
293         }
294     }
295     selectOverlayHolder_->OnHandleExistOverlay(info, requestCode);
296     NotifySelectOverlayShow(false);
297 }
298 
SwitchToHandleMode(HandleLevelMode mode,bool forceChange)299 void SelectContentOverlayManager::SwitchToHandleMode(HandleLevelMode mode, bool forceChange)
300 {
301     CHECK_NULL_VOID(shareOverlayInfo_);
302     if (shareOverlayInfo_->handleLevelMode == mode) {
303         return;
304     }
305     if (selectOverlayHolder_ && selectOverlayHolder_->GetCallback()) {
306         if (!forceChange && !selectOverlayHolder_->GetCallback()->CheckSwitchToMode(mode)) {
307             return;
308         }
309         selectOverlayHolder_->GetCallback()->OnHandleLevelModeChanged(mode);
310     }
311     TAG_LOGI(AceLogTag::ACE_SELECT_OVERLAY, "Set handle mode: %{public}d", mode);
312     shareOverlayInfo_->handleLevelMode = mode;
313     auto handleNode = handleNode_.Upgrade();
314     CHECK_NULL_VOID(handleNode);
315     if (mode == HandleLevelMode::OVERLAY) {
316         auto taskExecutor = Container::CurrentTaskExecutor();
317         taskExecutor->PostTask(
318             [weak = WeakClaim(this), node = handleNode] {
319                 auto manager = weak.Upgrade();
320                 CHECK_NULL_VOID(manager);
321                 CHECK_NULL_VOID(node);
322                 if (!manager->IsOpen()) {
323                     return;
324                 }
325                 manager->DestroySelectOverlayNode(node);
326                 manager->MountNodeToRoot(node, false);
327                 node->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
328             },
329             TaskExecutor::TaskType::UI, "SwitchToOverlayModeTask");
330         return;
331     }
332     if (mode == HandleLevelMode::EMBED) {
333         auto taskExecutor = Container::CurrentTaskExecutor();
334         taskExecutor->PostTask(
335             [weak = WeakClaim(this), node = handleNode] {
336                 auto manager = weak.Upgrade();
337                 CHECK_NULL_VOID(manager);
338                 CHECK_NULL_VOID(node);
339                 if (!manager->IsOpen()) {
340                     return;
341                 }
342                 manager->DestroySelectOverlayNode(node);
343                 manager->MountNodeToCaller(node, false);
344                 node->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
345             },
346             TaskExecutor::TaskType::UI, "SwitchToEmbedModeTask");
347     }
348 }
349 
MarkInfoChange(SelectOverlayDirtyFlag dirty)350 void SelectContentOverlayManager::MarkInfoChange(SelectOverlayDirtyFlag dirty)
351 {
352     CHECK_NULL_VOID(selectOverlayHolder_);
353     CHECK_NULL_VOID(IsOpen());
354     auto menuPattern = GetSelectMenuPattern(WeakClaim(this));
355     if (menuPattern) {
356         if ((dirty & DIRTY_SELECT_AREA) == DIRTY_SELECT_AREA) {
357             auto selectArea = selectOverlayHolder_->GetSelectArea();
358             menuPattern->UpdateSelectArea(selectArea);
359         }
360         if ((dirty & DIRTY_ALL_MENU_ITEM) == DIRTY_ALL_MENU_ITEM) {
361             SelectMenuInfo menuInfo;
362             selectOverlayHolder_->OnUpdateMenuInfo(menuInfo, DIRTY_ALL_MENU_ITEM);
363             menuPattern->UpdateSelectMenuInfo(menuInfo);
364         }
365         if ((dirty & DIRTY_COPY_ALL_ITEM) == DIRTY_COPY_ALL_ITEM) {
366             auto oldMenuInfo = menuPattern->GetSelectMenuInfo();
367             SelectMenuInfo menuInfo = { .showCopy = oldMenuInfo.showCopy, .showCopyAll = oldMenuInfo.showCopyAll };
368             selectOverlayHolder_->OnUpdateMenuInfo(menuInfo, DIRTY_COPY_ALL_ITEM);
369             oldMenuInfo.showCopyAll = menuInfo.showCopyAll;
370             oldMenuInfo.showCopy = menuInfo.showCopy;
371             menuPattern->UpdateSelectMenuInfo(oldMenuInfo);
372         }
373         if ((dirty & DIRTY_SELECT_TEXT) == DIRTY_SELECT_TEXT) {
374             auto selectedInfo = selectOverlayHolder_->GetSelectedText();
375             menuPattern->SetSelectInfo(selectedInfo);
376         }
377         if ((dirty & DIRTY_VIEWPORT) == DIRTY_VIEWPORT) {
378             auto viewPort = selectOverlayHolder_->GetAncestorNodeViewPort();
379             menuPattern->UpdateViewPort(viewPort);
380         }
381     }
382     UpdateHandleInfosWithFlag(dirty);
383     selectOverlayHolder_->OnHandleMarkInfoChange(shareOverlayInfo_, dirty);
384 }
385 
MarkSelectOverlayDirty(PropertyChangeFlag changeFlag)386 void SelectContentOverlayManager::MarkSelectOverlayDirty(PropertyChangeFlag changeFlag)
387 {
388     CHECK_NULL_VOID(IsOpen());
389     selectOverlayNode_.Upgrade()->MarkDirtyNode(changeFlag);
390 }
391 
UpdateHandleInfosWithFlag(int32_t updateFlag)392 void SelectContentOverlayManager::UpdateHandleInfosWithFlag(int32_t updateFlag)
393 {
394     auto pattern = GetSelectHandlePattern(WeakClaim(this));
395     CHECK_NULL_VOID(pattern);
396     std::optional<SelectHandleInfo> firstHandleInfo;
397     if ((static_cast<uint32_t>(updateFlag) & DIRTY_FIRST_HANDLE) == DIRTY_FIRST_HANDLE) {
398         firstHandleInfo = selectOverlayHolder_->GetFirstHandleInfo();
399     }
400     std::optional<SelectHandleInfo> secondHandleInfo;
401     if ((static_cast<uint32_t>(updateFlag) & DIRTY_SECOND_HANDLE) == DIRTY_SECOND_HANDLE) {
402         secondHandleInfo = selectOverlayHolder_->GetSecondHandleInfo();
403     }
404     if (!firstHandleInfo && !secondHandleInfo) {
405         return;
406     }
407     if (firstHandleInfo && secondHandleInfo) {
408         pattern->UpdateFirstAndSecondHandleInfo(*firstHandleInfo, *secondHandleInfo);
409     } else if (firstHandleInfo) {
410         pattern->UpdateFirstSelectHandleInfo(*firstHandleInfo);
411     } else {
412         pattern->UpdateSecondSelectHandleInfo(*secondHandleInfo);
413     }
414 }
415 
CreateSelectOverlay(SelectOverlayInfo & info,bool animation)416 void SelectContentOverlayManager::CreateSelectOverlay(SelectOverlayInfo& info, bool animation)
417 {
418     if (!info.enableHandleLevel) {
419         CreateNormalSelectOverlay(info, animation);
420         return;
421     }
422     CreateHandleLevelSelectOverlay(info, animation, info.handleLevelMode);
423 }
424 
CreateNormalSelectOverlay(SelectOverlayInfo & info,bool animation)425 void SelectContentOverlayManager::CreateNormalSelectOverlay(SelectOverlayInfo& info, bool animation)
426 {
427     shareOverlayInfo_ = std::make_shared<SelectOverlayInfo>(info);
428     auto overlayNode = SelectOverlayNode::CreateSelectOverlayNode(shareOverlayInfo_);
429     selectOverlayNode_ = overlayNode;
430     auto taskExecutor = Container::CurrentTaskExecutor();
431     taskExecutor->PostTask(
432         [animation, weak = WeakClaim(this), node = overlayNode] {
433             auto manager = weak.Upgrade();
434             CHECK_NULL_VOID(manager);
435             if (node && node == manager->selectOverlayNode_) {
436                 manager->MountNodeToRoot(node, animation);
437                 manager->NotifySelectOverlayShow(true);
438             }
439         },
440         TaskExecutor::TaskType::UI, "ArkUISelectOverlayCreate");
441 }
442 
CreateHandleLevelSelectOverlay(SelectOverlayInfo & info,bool animation,HandleLevelMode mode)443 void SelectContentOverlayManager::CreateHandleLevelSelectOverlay(
444     SelectOverlayInfo& info, bool animation, HandleLevelMode mode)
445 {
446     TAG_LOGI(AceLogTag::ACE_SELECT_OVERLAY,
447         "Show SelectOverlay, first %{public}s isShow %{public}d, second %{public}s isShow %{public}d",
448         info.firstHandle.paintRect.ToString().c_str(), info.firstHandle.isShow,
449         info.secondHandle.paintRect.ToString().c_str(), info.secondHandle.isShow);
450     shareOverlayInfo_ = std::make_shared<SelectOverlayInfo>(info);
451     auto menuNode = SelectOverlayNode::CreateSelectOverlayNode(shareOverlayInfo_, SelectOverlayMode::MENU_ONLY);
452     menuNode_ = menuNode;
453     auto handleNode = SelectOverlayNode::CreateSelectOverlayNode(shareOverlayInfo_, SelectOverlayMode::HANDLE_ONLY);
454     handleNode_ = handleNode;
455     auto taskExecutor = Container::CurrentTaskExecutorSafely();
456     CHECK_NULL_VOID(taskExecutor);
457     taskExecutor->PostTask(
458         [animation, weak = WeakClaim(this), menuNode, handleNode, mode] {
459             auto manager = weak.Upgrade();
460             CHECK_NULL_VOID(manager);
461             auto isMenuNodeValid = (menuNode && menuNode == manager->menuNode_);
462             auto isHandleNodeValid = (handleNode && handleNode == manager->handleNode_);
463             if (!isMenuNodeValid || !isHandleNodeValid) {
464                 return;
465             }
466             manager->MountNodeToRoot(menuNode, animation);
467             if (mode == HandleLevelMode::EMBED) {
468                 manager->MountNodeToCaller(handleNode, animation);
469             } else if (mode == HandleLevelMode::OVERLAY) {
470                 manager->MountNodeToRoot(handleNode, animation);
471             }
472             manager->NotifySelectOverlayShow(true);
473         },
474         TaskExecutor::TaskType::UI, "CreateHandleLevelSelectOverlay");
475 }
476 
MountNodeToRoot(const RefPtr<FrameNode> & overlayNode,bool animation)477 void SelectContentOverlayManager::MountNodeToRoot(const RefPtr<FrameNode>& overlayNode, bool animation)
478 {
479     auto rootNode = GetSelectOverlayRoot();
480     CHECK_NULL_VOID(rootNode);
481     const auto& children = rootNode->GetChildren();
482     auto slotIt = FindSelectOverlaySlot(rootNode, children);
483     auto index = static_cast<int32_t>(std::distance(children.begin(), slotIt));
484     auto slot = (index > 0) ? index : DEFAULT_NODE_SLOT;
485     for (auto it = slotIt; it != children.end(); ++it) {
486         // get keyboard index to put selet_overlay before keyboard node
487         if ((*it)->GetTag() == V2::KEYBOARD_ETS_TAG) {
488             slot = std::min(slot, index);
489             break;
490         }
491         // keep handle node before menu node
492         if ((*it)->GetTag() == V2::SELECT_OVERLAY_ETS_TAG) {
493             slot = index;
494             break;
495         }
496         // keep handle and menu node before magnifier
497         if ((*it)->GetTag() == V2::TEXTINPUT_ETS_TAG) {
498             slot = std::min(slot, index);
499             break;
500         }
501         index++;
502     }
503 
504     TAG_LOGI(AceLogTag::ACE_SELECT_OVERLAY, "MountNodeToRoot:%{public}s, id:%{public}d", rootNode->GetTag().c_str(),
505         rootNode->GetId());
506     overlayNode->MountToParent(rootNode, slot);
507     rootNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
508     if (!shareOverlayInfo_->isUsingMouse) {
509         auto node = DynamicCast<SelectOverlayNode>(overlayNode);
510         if (node) {
511             node->ShowSelectOverlay(animation);
512         }
513     }
514 }
515 
FindSelectOverlaySlot(const RefPtr<FrameNode> & root,const std::list<RefPtr<UINode>> & children)516 std::list<RefPtr<UINode>>::const_iterator SelectContentOverlayManager::FindSelectOverlaySlot(
517     const RefPtr<FrameNode>& root, const std::list<RefPtr<UINode>>& children)
518 {
519     auto begin = children.begin();
520     CHECK_NULL_RETURN(selectOverlayHolder_, begin);
521     auto callerNode = selectOverlayHolder_->GetOwner();
522     CHECK_NULL_RETURN(callerNode, begin);
523     RefPtr<UINode> prevNode = nullptr;
524     auto parent = callerNode->GetParent();
525     while (parent) {
526         if (parent == root) {
527             break;
528         }
529         prevNode = parent;
530         parent = parent->GetParent();
531     }
532     CHECK_NULL_RETURN(parent, begin);
533     CHECK_NULL_RETURN(prevNode, begin);
534     for (auto it = begin; it != children.end(); ++it) {
535         if (prevNode == *it) {
536             return ++it;
537         }
538     }
539     return begin;
540 }
541 
MountNodeToCaller(const RefPtr<FrameNode> & overlayNode,bool animation)542 void SelectContentOverlayManager::MountNodeToCaller(const RefPtr<FrameNode>& overlayNode, bool animation)
543 {
544     CHECK_NULL_VOID(selectOverlayHolder_);
545     auto ownerFrameNode = selectOverlayHolder_->GetOwner();
546     CHECK_NULL_VOID(ownerFrameNode);
547     TAG_LOGI(AceLogTag::ACE_SELECT_OVERLAY,
548         "Mount SelectOverlay node: %{public}s, id: %{public}d", ownerFrameNode->GetTag().c_str(),
549         ownerFrameNode->GetId());
550     ownerFrameNode->SetOverlayNode(overlayNode);
551     overlayNode->SetParent(AceType::WeakClaim(AceType::RawPtr(ownerFrameNode)));
552     overlayNode->SetActive(true);
553     auto overlayProperty = AceType::DynamicCast<LayoutProperty>(overlayNode->GetLayoutProperty());
554     CHECK_NULL_VOID(overlayProperty);
555     overlayProperty->SetIsOverlayNode(true);
556     overlayProperty->UpdateAlignment(Alignment::CENTER);
557     overlayProperty->UpdateMeasureType(MeasureType::MATCH_PARENT);
558     ownerFrameNode->MarkNeedSyncRenderTree();
559     ownerFrameNode->RebuildRenderContextTree();
560     overlayNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
561     if (!shareOverlayInfo_->isUsingMouse) {
562         auto node = DynamicCast<SelectOverlayNode>(overlayNode);
563         if (node) {
564             node->ShowSelectOverlay(animation);
565         }
566     }
567 }
568 
NotifySelectOverlayShow(bool isCreated)569 void SelectContentOverlayManager::NotifySelectOverlayShow(bool isCreated)
570 {
571     CHECK_NULL_VOID(selectOverlayHolder_);
572     auto callback = selectOverlayHolder_->GetCallback();
573     CHECK_NULL_VOID(callback);
574     callback->OnAfterSelectOverlayShow(isCreated);
575 }
576 
GetSelectOverlayRoot()577 const RefPtr<FrameNode> SelectContentOverlayManager::GetSelectOverlayRoot()
578 {
579     auto rootNode = rootNodeWeak_.Upgrade();
580     CHECK_NULL_RETURN(shareOverlayInfo_, rootNode);
581     auto container = Container::Current();
582     if (container && container->IsScenceBoardWindow()) {
583         auto root = FindWindowScene(shareOverlayInfo_->callerFrameNode.Upgrade());
584         rootNode = DynamicCast<FrameNode>(root);
585     }
586     return rootNode;
587 }
588 
589 /**
590  * @description: This function will be used in SceneBoard Thread only.
591  * if need to show the select-overlay component, it expects to receive the target component bound by
592  * the select-overlay component to find the windowScene component.
593  * if need to hide the select-overlay component, it expects to receive the the select-overlay component
594  * to return the parent component. And the parent component will be the windowScene component exactly.
595  */
FindWindowScene(RefPtr<FrameNode> targetNode)596 RefPtr<UINode> SelectContentOverlayManager::FindWindowScene(RefPtr<FrameNode> targetNode)
597 {
598     auto container = Container::Current();
599     if (!container || !container->IsScenceBoardWindow()) {
600         return rootNodeWeak_.Upgrade();
601     }
602     CHECK_NULL_RETURN(targetNode, nullptr);
603     auto parent = targetNode->GetParent();
604     while (parent && parent->GetTag() != V2::WINDOW_SCENE_ETS_TAG) {
605         parent = parent->GetParent();
606     }
607     CHECK_NULL_RETURN(parent, nullptr);
608     return parent;
609 }
610 
CloseInternal(int32_t id,bool animation,CloseReason reason)611 bool SelectContentOverlayManager::CloseInternal(int32_t id, bool animation, CloseReason reason)
612 {
613     CHECK_NULL_RETURN(selectOverlayHolder_, false);
614     CHECK_NULL_RETURN(selectOverlayHolder_->GetOwnerId() == id, false);
615     CHECK_NULL_RETURN(shareOverlayInfo_, false);
616     LOGI("SelectOverlay: Close selectoverlay by id %{public}d, reason %{public}d", id, reason);
617     auto callback = selectOverlayHolder_->GetCallback();
618     auto menuType = shareOverlayInfo_->menuInfo.menuType;
619     auto pattern = GetSelectHandlePattern(WeakClaim(this));
620     RefPtr<OverlayInfo> info = nullptr;
621     if (pattern) {
622         info = AceType::MakeRefPtr<OverlayInfo>();
623         info->isSingleHandle = shareOverlayInfo_->isSingleHandle;
624         info->isShowMenu = shareOverlayInfo_->menuInfo.menuIsShow;
625         info->isHiddenHandle = pattern->IsHiddenHandle();
626     }
627     auto selectOverlayNode = selectOverlayNode_.Upgrade();
628     auto menuNode = menuNode_.Upgrade();
629     auto handleNode = handleNode_.Upgrade();
630     if (animation && !shareOverlayInfo_->isUsingMouse) {
631         ClearAllStatus();
632         DestroySelectOverlayNodeWithAnimation(selectOverlayNode);
633         DestroySelectOverlayNodeWithAnimation(menuNode);
634         DestroySelectOverlayNodeWithAnimation(handleNode);
635     } else {
636         DestroySelectOverlayNode(selectOverlayNode);
637         DestroySelectOverlayNode(menuNode);
638         DestroySelectOverlayNode(handleNode);
639         ClearAllStatus();
640     }
641     if (callback) {
642         callback->OnCloseOverlay(menuType, reason, info);
643     }
644     return true;
645 }
646 
DestroySelectOverlayNodeWithAnimation(const RefPtr<FrameNode> & node)647 void SelectContentOverlayManager::DestroySelectOverlayNodeWithAnimation(const RefPtr<FrameNode>& node)
648 {
649     auto overlayNode = DynamicCast<SelectOverlayNode>(node);
650     CHECK_NULL_VOID(overlayNode);
651     overlayNode->HideSelectOverlay([weakOverlay = WeakClaim(AceType::RawPtr(node)), managerWeak = WeakClaim(this)]() {
652         auto manager = managerWeak.Upgrade();
653         CHECK_NULL_VOID(manager);
654         manager->DestroySelectOverlayNode(weakOverlay.Upgrade());
655     });
656 }
657 
DestroySelectOverlayNode(const RefPtr<FrameNode> & overlay)658 void SelectContentOverlayManager::DestroySelectOverlayNode(const RefPtr<FrameNode>& overlay)
659 {
660     CHECK_NULL_VOID(overlay);
661     auto parentNode = overlay->GetParent();
662     CHECK_NULL_VOID(parentNode);
663 
664     auto parentFrameNode = DynamicCast<FrameNode>(parentNode);
665     if (parentFrameNode) {
666         auto pattern = overlay->GetPattern<SelectOverlayPattern>();
667         if (pattern && pattern->GetMode() == SelectOverlayMode::HANDLE_ONLY) {
668             parentFrameNode->SetOverlayNode(nullptr);
669             overlay->SetParent(nullptr);
670         }
671     }
672     TAG_LOGI(AceLogTag::ACE_SELECT_OVERLAY,
673         "Remove node [%{public}s, %{public}d] from [%{public}s, %{public}d]", overlay->GetTag().c_str(),
674         overlay->GetId(), parentNode->GetTag().c_str(), parentNode->GetId());
675     parentNode->RemoveChild(overlay);
676     parentNode->MarkNeedSyncRenderTree();
677     parentNode->RebuildRenderContextTree();
678 }
679 
ClearAllStatus()680 void SelectContentOverlayManager::ClearAllStatus()
681 {
682     selectOverlayNode_.Reset();
683     handleNode_.Reset();
684     menuNode_.Reset();
685     shareOverlayInfo_.reset();
686     if (selectOverlayHolder_) {
687         selectOverlayHolder_->OnBind(nullptr);
688     }
689     selectOverlayHolder_.Reset();
690 }
691 
CloseCurrent(bool animation,CloseReason reason)692 bool SelectContentOverlayManager::CloseCurrent(bool animation, CloseReason reason)
693 {
694     CHECK_NULL_RETURN(selectOverlayHolder_, false);
695     CHECK_NULL_RETURN(selectOverlayNode_.Upgrade() || menuNode_.Upgrade() || handleNode_.Upgrade(), false);
696     return CloseInternal(selectOverlayHolder_->GetOwnerId(), animation, reason);
697 }
698 
CloseWithOverlayId(int32_t overlayId,CloseReason reason,bool animation)699 void SelectContentOverlayManager::CloseWithOverlayId(int32_t overlayId, CloseReason reason, bool animation)
700 {
701     CHECK_NULL_VOID(IsOpen());
702     // call from menu button.
703     auto hasOverlayId = (selectOverlayNode_.Upgrade() && overlayId == selectOverlayNode_.Upgrade()->GetId());
704     hasOverlayId = hasOverlayId || (menuNode_.Upgrade() && menuNode_.Upgrade()->GetId());
705     if (hasOverlayId) {
706         CloseInternal(selectOverlayHolder_->GetOwnerId(), animation, reason);
707     }
708 }
709 
Close(int32_t id,bool animation,CloseReason reason)710 void SelectContentOverlayManager::Close(int32_t id, bool animation, CloseReason reason)
711 {
712     CloseInternal(id, animation, reason);
713 }
714 
ShowOptionMenu()715 void SelectContentOverlayManager::ShowOptionMenu()
716 {
717     auto pattern = GetSelectMenuPattern(WeakClaim(this));
718     CHECK_NULL_VOID(pattern);
719     pattern->UpdateMenuIsShow(true);
720 }
721 
HideOptionMenu(bool noAnimation)722 void SelectContentOverlayManager::HideOptionMenu(bool noAnimation)
723 {
724     auto pattern = GetSelectMenuPattern(WeakClaim(this));
725     CHECK_NULL_VOID(pattern);
726     pattern->UpdateMenuIsShow(false, noAnimation);
727 }
728 
ToggleOptionMenu()729 void SelectContentOverlayManager::ToggleOptionMenu()
730 {
731     CHECK_NULL_VOID(shareOverlayInfo_);
732     auto pattern = GetSelectMenuPattern(WeakClaim(this));
733     CHECK_NULL_VOID(pattern);
734     pattern->UpdateMenuIsShow(!shareOverlayInfo_->menuInfo.menuIsShow);
735 }
736 
DisableMenu()737 void SelectContentOverlayManager::DisableMenu()
738 {
739     auto pattern = GetSelectMenuPattern(WeakClaim(this));
740     CHECK_NULL_VOID(pattern);
741     pattern->DisableMenu(true);
742 }
743 
EnableMenu()744 void SelectContentOverlayManager::EnableMenu()
745 {
746     auto pattern = GetSelectMenuPattern(WeakClaim(this));
747     CHECK_NULL_VOID(pattern);
748     pattern->DisableMenu(false);
749 }
750 
HideHandle()751 void SelectContentOverlayManager::HideHandle()
752 {
753     auto pattern = GetSelectHandlePattern(WeakClaim(this));
754     CHECK_NULL_VOID(pattern);
755     pattern->StartHiddenHandleTask(false);
756 }
757 
IsOpen()758 bool SelectContentOverlayManager::IsOpen()
759 {
760     if (!IsEnableHandleLevel()) {
761         auto overlayNode = selectOverlayNode_.Upgrade();
762         return overlayNode && overlayNode->GetParent();
763     }
764     auto hasHandleNode = handleNode_.Upgrade() && handleNode_.Upgrade()->GetParent();
765     auto hasMenuNode = menuNode_.Upgrade() && menuNode_.Upgrade()->GetParent();
766     return hasHandleNode || hasMenuNode;
767 }
768 
IsCreating()769 bool SelectContentOverlayManager::IsCreating()
770 {
771     if (!IsEnableHandleLevel()) {
772         auto overlayNode = selectOverlayNode_.Upgrade();
773         return overlayNode && !overlayNode->GetParent();
774     }
775     auto menuNode = menuNode_.Upgrade();
776     auto handleNode = handleNode_.Upgrade();
777     return (menuNode && !menuNode->GetParent()) || (handleNode && !handleNode->GetParent());
778 }
779 
IsMenuShow()780 bool SelectContentOverlayManager::IsMenuShow()
781 {
782     return IsOpen() && shareOverlayInfo_ && shareOverlayInfo_->menuInfo.menuIsShow;
783 }
784 
IsSingleHandle()785 bool SelectContentOverlayManager::IsSingleHandle()
786 {
787     return IsOpen() && shareOverlayInfo_ && shareOverlayInfo_->isSingleHandle;
788 }
789 
IsHandlesShow()790 bool SelectContentOverlayManager::IsHandlesShow()
791 {
792     return IsOpen() && shareOverlayInfo_ && !shareOverlayInfo_->isSingleHandle;
793 }
794 
IsHandleReverse()795 bool SelectContentOverlayManager::IsHandleReverse()
796 {
797     return IsOpen() && shareOverlayInfo_ && shareOverlayInfo_->handleReverse;
798 }
799 
RestartHiddenHandleTask(bool isDelay)800 void SelectContentOverlayManager::RestartHiddenHandleTask(bool isDelay)
801 {
802     auto pattern = GetSelectHandlePattern(WeakClaim(this));
803     CHECK_NULL_VOID(pattern);
804     pattern->RestartHiddenHandleTask(isDelay);
805 }
806 
CancelHiddenHandleTask()807 void SelectContentOverlayManager::CancelHiddenHandleTask()
808 {
809     auto pattern = GetSelectHandlePattern(WeakClaim(this));
810     CHECK_NULL_VOID(pattern);
811     pattern->CancelHiddenHandleTask();
812 }
813 
GetSelectOverlayNode()814 RefPtr<SelectOverlayNode> SelectContentOverlayManager::GetSelectOverlayNode()
815 {
816     auto overlayNode = IsEnableHandleLevel() ? menuNode_.Upgrade() : selectOverlayNode_.Upgrade();
817     return AceType::DynamicCast<SelectOverlayNode>(overlayNode);
818 }
819 
GetShowMenuType()820 OptionMenuType SelectContentOverlayManager::GetShowMenuType()
821 {
822     return IsOpen() && shareOverlayInfo_ ? shareOverlayInfo_->menuInfo.menuType : OptionMenuType::NO_MENU;
823 }
824 
HandleGlobalEvent(const TouchEvent & touchEvent,const NG::OffsetF & rootOffset)825 void SelectContentOverlayManager::HandleGlobalEvent(const TouchEvent& touchEvent, const NG::OffsetF& rootOffset)
826 {
827     NG::PointF point { touchEvent.x - rootOffset.GetX(), touchEvent.y - rootOffset.GetY() };
828     if (touchEvent.type == TouchType::DOWN) {
829         isIntercept_ = IsTouchInSelectOverlayArea(point);
830     }
831     if (!isIntercept_) {
832         HandleSelectionEvent(point, touchEvent);
833         if (selectOverlayHolder_ && selectOverlayHolder_->GetCallback() && selectOverlayHolder_->GetOwner()) {
834             auto localPoint = point;
835             ConvertPointRelativeToNode(selectOverlayHolder_->GetOwner(), localPoint);
836             selectOverlayHolder_->GetCallback()->OnHandleGlobalEvent(point, localPoint, touchEvent);
837         }
838     }
839     if (touchEvent.type == TouchType::UP) {
840         isIntercept_ = false;
841     }
842 }
843 
IsTouchInSelectOverlayArea(const PointF & point)844 bool SelectContentOverlayManager::IsTouchInSelectOverlayArea(const PointF& point)
845 {
846     if (!IsEnableHandleLevel()) {
847         return IsTouchInNormalSelectOverlayArea(point);
848     }
849     return IsTouchInHandleLevelOverlayArea(point);
850 }
851 
IsTouchInNormalSelectOverlayArea(const PointF & point)852 bool SelectContentOverlayManager::IsTouchInNormalSelectOverlayArea(const PointF& point)
853 {
854     auto current = selectOverlayNode_.Upgrade();
855     CHECK_NULL_RETURN(current, false);
856     auto selectOverlayNode = DynamicCast<SelectOverlayNode>(current);
857     if (selectOverlayNode) {
858         return selectOverlayNode->IsInSelectedOrSelectOverlayArea(point);
859     }
860     // get the menu rect not the out wrapper
861     const auto& children = current->GetChildren();
862     for (const auto& it : children) {
863         auto child = DynamicCast<FrameNode>(it);
864         if (child == nullptr || !child->GetGeometryNode()) {
865             continue;
866         }
867         auto frameRect = RectF(child->GetTransformRelativeOffset(), child->GetGeometryNode()->GetFrameSize());
868         if (frameRect.IsInRegion(point)) {
869             return true;
870         }
871     }
872     return false;
873 }
874 
IsTouchInHandleLevelOverlayArea(const PointF & point)875 bool SelectContentOverlayManager::IsTouchInHandleLevelOverlayArea(const PointF& point)
876 {
877     auto selectOverlayNode = DynamicCast<SelectOverlayNode>(menuNode_.Upgrade());
878     if (selectOverlayNode && selectOverlayNode->IsInSelectedOrSelectOverlayArea(point)) {
879         return true;
880     }
881     selectOverlayNode = DynamicCast<SelectOverlayNode>(handleNode_.Upgrade());
882     CHECK_NULL_RETURN(selectOverlayNode, false);
883     auto localPoint = point;
884     ConvertPointRelativeToNode(selectOverlayNode->GetAncestorNodeOfFrame(), localPoint);
885     return selectOverlayNode->IsInSelectedOrSelectOverlayArea(localPoint);
886 }
887 
HandleSelectionEvent(const PointF & point,const TouchEvent & rawTouchEvent)888 void SelectContentOverlayManager::HandleSelectionEvent(const PointF& point, const TouchEvent& rawTouchEvent)
889 {
890     CHECK_NULL_VOID(holdSelectionInfo_);
891     CHECK_NULL_VOID(holdSelectionInfo_->checkTouchInArea);
892     CHECK_NULL_VOID(holdSelectionInfo_->resetSelectionCallback);
893     if (holdSelectionInfo_->IsAcceptEvent(rawTouchEvent.sourceType, rawTouchEvent.type) &&
894         !holdSelectionInfo_->checkTouchInArea(point) && !IsOpen()) {
895         ResetSelectionRect();
896     }
897 }
898 
ResetSelectionRect()899 void SelectContentOverlayManager::ResetSelectionRect()
900 {
901     CHECK_NULL_VOID(holdSelectionInfo_);
902     if (holdSelectionInfo_->resetSelectionCallback) {
903         holdSelectionInfo_->resetSelectionCallback();
904     }
905     selectionHoldId_ = -1;
906     holdSelectionInfo_.reset();
907 }
908 
SetHoldSelectionCallback(int32_t id,const HoldSelectionInfo & selectionInfo)909 void SelectContentOverlayManager::SetHoldSelectionCallback(int32_t id, const HoldSelectionInfo& selectionInfo)
910 {
911     if (id == selectionHoldId_) {
912         return;
913     }
914     if (holdSelectionInfo_ && id != selectionHoldId_ && holdSelectionInfo_->resetSelectionCallback) {
915         holdSelectionInfo_->resetSelectionCallback();
916     }
917     selectionHoldId_ = id;
918     holdSelectionInfo_ = selectionInfo;
919 }
920 
RemoveHoldSelectionCallback(int32_t id)921 void SelectContentOverlayManager::RemoveHoldSelectionCallback(int32_t id)
922 {
923     CHECK_NULL_VOID(holdSelectionInfo_);
924     if (selectionHoldId_ == id) {
925         selectionHoldId_ = -1;
926         holdSelectionInfo_.reset();
927     }
928 }
929 
IsEnableHandleLevel()930 bool SelectContentOverlayManager::IsEnableHandleLevel()
931 {
932     return shareOverlayInfo_ && shareOverlayInfo_->enableHandleLevel;
933 }
934 
GetMenuPattern()935 RefPtr<Pattern> SelectContentOverlayManager::GetMenuPattern()
936 {
937     return IsEnableHandleLevel() ? GetSelectOverlayPattern(menuNode_)
938                                       : GetSelectOverlayPattern(selectOverlayNode_);
939 }
940 
GetHandlePattern()941 RefPtr<Pattern> SelectContentOverlayManager::GetHandlePattern()
942 {
943     return IsEnableHandleLevel() ? GetSelectOverlayPattern(handleNode_)
944                                       : GetSelectOverlayPattern(selectOverlayNode_);
945 }
946 
GetHandleOverlayNode()947 RefPtr<FrameNode> SelectContentOverlayManager::GetHandleOverlayNode()
948 {
949     return handleNode_.Upgrade();
950 }
951 
NotifyUpdateToolBar(bool itemChanged)952 void SelectContentOverlayManager::NotifyUpdateToolBar(bool itemChanged)
953 {
954     auto menuNode = DynamicCast<SelectOverlayNode>(menuNode_.Upgrade());
955     CHECK_NULL_VOID(menuNode);
956     menuNode->UpdateToolBar(itemChanged);
957 }
958 
GetHandleDiameter()959 float SelectContentOverlayManager::GetHandleDiameter()
960 {
961     return SelectOverlayPattern::GetHandleDiameter();
962 }
963 
ConvertPointRelativeToNode(const RefPtr<FrameNode> & node,PointF & point)964 void SelectContentOverlayManager::ConvertPointRelativeToNode(const RefPtr<FrameNode>& node, PointF& point)
965 {
966     CHECK_NULL_VOID(node);
967     auto rootNode = GetSelectOverlayRoot();
968     CHECK_NULL_VOID(rootNode);
969     std::stack<RefPtr<FrameNode>> nodeStack;
970     auto parent = node;
971     while (parent && parent != rootNode) {
972         nodeStack.push(parent);
973         parent = parent->GetAncestorNodeOfFrame();
974     }
975     CHECK_NULL_VOID(!nodeStack.empty());
976     PointF temp(point.GetX(), point.GetY());
977     while (!nodeStack.empty()) {
978         parent = nodeStack.top();
979         CHECK_NULL_VOID(parent);
980         nodeStack.pop();
981         auto renderContext = parent->GetRenderContext();
982         CHECK_NULL_VOID(renderContext);
983         renderContext->GetPointWithRevert(temp);
984         auto rectOffset = renderContext->GetPaintRectWithoutTransform().GetOffset();
985         temp = temp - rectOffset;
986     }
987     point.SetX(temp.GetX());
988     point.SetY(temp.GetY());
989 }
990 
IsTouchAtHandle(const PointF & localPoint,const PointF & globalPoint)991 bool SelectContentOverlayManager::IsTouchAtHandle(const PointF& localPoint, const PointF& globalPoint)
992 {
993     auto handleNode = handleNode_.Upgrade();
994     CHECK_NULL_RETURN(handleNode, false);
995     auto selectOverlayNode = DynamicCast<SelectOverlayNode>(handleNode);
996     CHECK_NULL_RETURN(selectOverlayNode, false);
997     CHECK_NULL_RETURN(selectOverlayHolder_, false);
998     if (selectOverlayNode->GetParent() == selectOverlayHolder_->GetOwner()) {
999         return selectOverlayNode->IsInSelectedOrSelectOverlayArea(localPoint);
1000     }
1001     return selectOverlayNode->IsInSelectedOrSelectOverlayArea(globalPoint);
1002 }
1003 
UpdateViewPort()1004 void SelectContentOverlayManager::UpdateViewPort()
1005 {
1006     auto menuNode = menuNode_.Upgrade();
1007     CHECK_NULL_VOID(menuNode);
1008     CHECK_NULL_VOID(selectOverlayHolder_);
1009     CHECK_NULL_VOID(shareOverlayInfo_);
1010     shareOverlayInfo_->ancestorViewPort = selectOverlayHolder_->GetAncestorNodeViewPort();
1011     menuNode->MarkDirtyNode(PROPERTY_UPDATE_LAYOUT);
1012 }
1013 
SetHandleCircleIsShow(bool isFirst,bool isShow)1014 void SelectContentOverlayManager::SetHandleCircleIsShow(bool isFirst, bool isShow)
1015 {
1016     auto pattern = GetSelectHandlePattern(WeakClaim(this));
1017     CHECK_NULL_VOID(pattern);
1018     pattern->SetHandleCircleIsShow(isFirst, isShow);
1019 }
1020 
SetIsHandleLineShow(bool isShow)1021 void SelectContentOverlayManager::SetIsHandleLineShow(bool isShow)
1022 {
1023     auto pattern = GetSelectHandlePattern(WeakClaim(this));
1024     CHECK_NULL_VOID(pattern);
1025     pattern->SetIsHandleLineShow(isShow);
1026 }
1027 
MarkHandleDirtyNode(PropertyChangeFlag flag)1028 void SelectContentOverlayManager::MarkHandleDirtyNode(PropertyChangeFlag flag)
1029 {
1030     auto pattern = GetSelectHandlePattern(WeakClaim(this));
1031     CHECK_NULL_VOID(pattern);
1032     auto host = pattern->GetHost();
1033     CHECK_NULL_VOID(host);
1034     host->MarkDirtyNode(flag);
1035 }
1036 } // namespace OHOS::Ace::NG
1037