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