1 /* 2 * Copyright (c) 2022-2023 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_PATTERNS_OVERLAY_OVERLAY_MANAGER_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_OVERLAY_OVERLAY_MANAGER_H 18 19 #include <cstdint> 20 #include <functional> 21 #include <unordered_map> 22 #include <utility> 23 24 #include "base/memory/ace_type.h" 25 #include "base/memory/referenced.h" 26 #include "base/utils/noncopyable.h" 27 #include "core/components/common/properties/placement.h" 28 #include "core/components/dialog/dialog_properties.h" 29 #include "core/components/picker/picker_data.h" 30 #include "core/components_ng/base/ui_node.h" 31 #include "core/components_ng/pattern/calendar_picker/calendar_type_define.h" 32 #include "core/components_ng/pattern/overlay/modal_style.h" 33 #include "core/components_ng/pattern/overlay/sheet_style.h" 34 #include "core/components_ng/pattern/picker/datepicker_event_hub.h" 35 #include "core/components_ng/pattern/picker/picker_type_define.h" 36 #include "core/components_ng/pattern/text_picker/textpicker_event_hub.h" 37 #include "core/pipeline_ng/ui_task_scheduler.h" 38 39 namespace OHOS::Ace { 40 struct ModalUIExtensionCallbacks; 41 } // namespace OHOS::Ace 42 43 namespace OHOS::AAFwk { 44 class Want; 45 } // namespace OHOS::AAFwk 46 47 namespace OHOS::Ace::NG { 48 49 struct PopupInfo { 50 int32_t popupId = -1; 51 WeakPtr<FrameNode> target; 52 RefPtr<FrameNode> popupNode; 53 bool markNeedUpdate = false; 54 bool isCurrentOnShow = false; 55 bool isBlockEvent = true; 56 SizeF targetSize; 57 OffsetF targetOffset; 58 }; 59 60 // StageManager is the base class for root render node to perform page switch. 61 class ACE_EXPORT OverlayManager : public virtual AceType { 62 DECLARE_ACE_TYPE(OverlayManager, AceType); 63 64 public: OverlayManager(const RefPtr<FrameNode> & rootNode)65 explicit OverlayManager(const RefPtr<FrameNode>& rootNode) : rootNodeWeak_(rootNode) {} ~OverlayManager()66 ~OverlayManager() override 67 { 68 LOGI("OverlayManager Destructor."); 69 popupMap_.clear(); 70 } 71 void ShowIndexerPopup(int32_t targetId, RefPtr<FrameNode>& customNode); 72 void RemoveIndexerPopupById(int32_t targetId); 73 void RemoveIndexerPopup(); 74 void HidePopup(int32_t targetId, const PopupInfo& popupInfo); 75 void ShowPopup(int32_t targetId, const PopupInfo& popupInfo); 76 void ErasePopup(int32_t targetId); 77 void HideAllPopups(); 78 void HideCustomPopups(); 79 GetPopupInfo(int32_t targetId)80 PopupInfo GetPopupInfo(int32_t targetId) const 81 { 82 auto it = popupMap_.find(targetId); 83 if (it == popupMap_.end()) { 84 return {}; 85 } 86 return it->second; 87 } 88 HasPopupInfo(int32_t targetId)89 bool HasPopupInfo(int32_t targetId) const 90 { 91 if (popupMap_.find(targetId) != popupMap_.end()) { 92 return true; 93 } 94 return false; 95 } 96 97 void ShowMenu(int32_t targetId, const NG::OffsetF& offset, RefPtr<FrameNode> menu = nullptr); 98 void HideMenu(const RefPtr<FrameNode>& menu, int32_t targetId, bool isMenuOnTouch = false); 99 void DeleteMenu(int32_t targetId); 100 void ShowMenuInSubWindow(int32_t targetId, const NG::OffsetF& offset, RefPtr<FrameNode> menu = nullptr); 101 void HideMenuInSubWindow(const RefPtr<FrameNode>& menu, int32_t targetId); 102 void HideMenuInSubWindow(); 103 void CleanMenuInSubWindow(); 104 void HideAllMenus(); 105 106 void ShowToast(const std::string& message, int32_t duration, const std::string& bottom, bool isRightToLeft); 107 108 // customNode only used by customDialog, pass in nullptr if not customDialog 109 RefPtr<FrameNode> ShowDialog( 110 const DialogProperties& dialogProps, std::function<void()>&& buildFunc, bool isRightToLeft = false); 111 void ShowCustomDialog(const RefPtr<FrameNode>& customNode); 112 void ShowDateDialog(const DialogProperties& dialogProps, const DatePickerSettingData& settingData, 113 std::map<std::string, NG::DialogEvent> dialogEvent, 114 std::map<std::string, NG::DialogGestureEvent> dialogCancelEvent); 115 void ShowTimeDialog(const DialogProperties& dialogProps, const TimePickerSettingData& settingData, 116 std::map<std::string, PickerTime> timePickerProperty, std::map<std::string, NG::DialogEvent> dialogEvent, 117 std::map<std::string, NG::DialogGestureEvent> dialogCancelEvent); 118 void ShowTextDialog(const DialogProperties& dialogProps, const TextPickerSettingData& settingData, 119 std::map<std::string, NG::DialogTextEvent> dialogEvent, 120 std::map<std::string, NG::DialogGestureEvent> dialogCancelEvent); 121 void ShowCalendarDialog(const DialogProperties& dialogProps, const CalendarSettingData& settingData, 122 std::map<std::string, NG::DialogEvent> dialogEvent, 123 std::map<std::string, NG::DialogGestureEvent> dialogCancelEvent); 124 125 void CloseDialog(const RefPtr<FrameNode>& dialogNode); 126 127 /** pop overlays (if any) on back press 128 * 129 * @return true if popup was removed, false if no overlay exists 130 */ 131 bool RemoveOverlay(bool isBackPressed, bool isPageRouter = false); 132 bool RemoveDialog(const RefPtr<FrameNode>& overlay, bool isBackPressed, bool isPageRouter); 133 bool RemoveBubble(const RefPtr<FrameNode>& overlay); 134 bool RemoveMenu(const RefPtr<FrameNode>& overlay); 135 bool RemoveModalInOverlay(); 136 bool RemoveAllModalInOverlay(); 137 bool RemoveOverlayInSubwindow(); 138 RegisterOnHideMenu(std::function<void ()> callback)139 void RegisterOnHideMenu(std::function<void()> callback) 140 { 141 onHideMenuCallback_ = callback; 142 } 143 RegisterOnShowMenu(const std::function<void ()> & callback)144 void RegisterOnShowMenu(const std::function<void()>& callback) 145 { 146 onShowMenuCallback_ = callback; 147 } 148 RegisterOnHideDialog(std::function<void ()> callback)149 void RegisterOnHideDialog(std::function<void()> callback) 150 { 151 onHideDialogCallback_ = callback; 152 } 153 CallOnShowMenuCallback()154 void CallOnShowMenuCallback() 155 { 156 if (onShowMenuCallback_) { 157 onShowMenuCallback_(); 158 } 159 } 160 CallOnHideMenuCallback()161 void CallOnHideMenuCallback() 162 { 163 if (onHideMenuCallback_) { 164 onHideMenuCallback_(); 165 } 166 } 167 CallOnHideDialogCallback()168 void CallOnHideDialogCallback() 169 { 170 if (onHideDialogCallback_) { 171 onHideDialogCallback_(); 172 } 173 } 174 SetBackPressEvent(std::function<bool ()> event)175 void SetBackPressEvent(std::function<bool()> event) 176 { 177 backPressEvent_ = event; 178 } 179 FireBackPressEvent()180 bool FireBackPressEvent() const 181 { 182 if (backPressEvent_) { 183 return backPressEvent_(); 184 } 185 return false; 186 } 187 188 #ifdef ENABLE_DRAG_FRAMEWORK GetHasPixelMap()189 bool GetHasPixelMap() 190 { 191 return hasPixelMap_; 192 } 193 SetHasPixelMap(bool hasPixelMap)194 void SetHasPixelMap(bool hasPixelMap) 195 { 196 hasPixelMap_ = hasPixelMap; 197 } 198 GetPixelMapNode()199 RefPtr<FrameNode> GetPixelMapNode() 200 { 201 return pixmapColumnNodeWeak_.Upgrade(); 202 } 203 GetHasFilter()204 bool GetHasFilter() 205 { 206 return hasFilter_; 207 } 208 SetHasFilter(bool hasFilter)209 void SetHasFilter(bool hasFilter) 210 { 211 hasFilter_ = hasFilter; 212 } 213 GetHasEvent()214 bool GetHasEvent() 215 { 216 return hasEvent_; 217 } 218 SetHasEvent(bool hasEvent)219 void SetHasEvent(bool hasEvent) 220 { 221 hasEvent_ = hasEvent; 222 } 223 GetIsOnAnimation()224 bool GetIsOnAnimation() 225 { 226 return isOnAnimation_; 227 } 228 SetIsOnAnimation(bool isOnAnimation)229 void SetIsOnAnimation(bool isOnAnimation) 230 { 231 isOnAnimation_ = isOnAnimation; 232 } 233 SetFilterColumnNode(const RefPtr<FrameNode> & columnNode)234 void SetFilterColumnNode(const RefPtr<FrameNode>& columnNode) 235 { 236 filterColumnNodeWeak_ = columnNode; 237 } 238 void MountFilterToWindowScene(const RefPtr<FrameNode>& columnNode, const RefPtr<UINode>& windowScene); 239 void MountPixelMapToWindowScene(const RefPtr<FrameNode>& columnNode, const RefPtr<UINode>& windowScene); 240 void MountEventToWindowScene(const RefPtr<FrameNode>& columnNode, const RefPtr<UINode>& windowScene); 241 void MountPixelMapToRootNode(const RefPtr<FrameNode>& columnNode); 242 void MountEventToRootNode(const RefPtr<FrameNode>& columnNode); 243 void RemovePixelMap(); 244 void RemovePixelMapAnimation(bool startDrag, double x, double y); 245 void UpdatePixelMapScale(float& scale); 246 void RemoveFilter(); 247 void RemoveEventColumn(); 248 #endif // ENABLE_DRAG_FRAMEWORK 249 void BindContentCover(bool isShow, std::function<void(const std::string&)>&& callback, 250 std::function<RefPtr<UINode>()>&& buildNodeFunc, NG::ModalStyle& modalStyle, 251 std::function<void()>&& onAppear, std::function<void()>&& onDisappear, int32_t targetId); 252 253 void BindSheet(bool isShow, std::function<void(const std::string&)>&& callback, 254 std::function<RefPtr<UINode>()>&& buildNodeFunc, NG::SheetStyle& sheetStyle, 255 std::function<void()>&& onAppear, std::function<void()>&& onDisappear, int32_t targetId); 256 257 void DestroySheet(const RefPtr<FrameNode>& sheetNode, int32_t targetId); 258 259 static void DestroySheetMask(const RefPtr<FrameNode>& sheetNode); 260 261 void DeleteModal(int32_t targetId); 262 263 void BindKeyboard(const std::function<void()>& keybordBuilder, int32_t targetId); 264 void CloseKeyboard(int32_t targetId); 265 void DestroyKeyboard(); 266 267 RefPtr<UINode> FindWindowScene(RefPtr<FrameNode> targetNode); 268 269 // ui extension 270 int32_t CreateModalUIExtension(const AAFwk::Want& want, const ModalUIExtensionCallbacks& callbacks); 271 void CloseModalUIExtension(int32_t sessionId); 272 273 void MarkDirty(PropertyChangeFlag flag); 274 float GetRootHeight() const; 275 276 private: 277 void PopToast(int32_t targetId); 278 279 // toast should contain id to avoid multiple delete. 280 std::unordered_map<int32_t, WeakPtr<FrameNode>> toastMap_; 281 282 /** find/register menu node and update menu's display position 283 * 284 * @return true if process is successful 285 */ 286 bool ShowMenuHelper(RefPtr<FrameNode>& menu, int32_t targetId, const NG::OffsetF& offset); 287 288 // The focus logic of overlay node (menu and dialog): 289 // 1. before start show animation: lower level node set unfocusabel and lost focus; 290 // 2. end show animation: overlay node get focus; 291 // 3. before start hide animation: lower level node set focusable; 292 // 4. end hide animation: overlay node lost focus, lower level node get focus. 293 void FocusOverlayNode(const RefPtr<FrameNode>& overlayNode, bool isInSubWindow = false); 294 void BlurOverlayNode(const RefPtr<FrameNode>& currentOverlay, bool isInSubWindow = false); 295 void BlurLowerNode(const RefPtr<FrameNode>& currentOverlay); 296 void ResetLowerNodeFocusable(const RefPtr<FrameNode>& currentOverlay); 297 void PostDialogFinishEvent(const WeakPtr<FrameNode>& nodeWk); 298 void OnDialogCloseEvent(const RefPtr<FrameNode>& node); 299 300 void SetShowMenuAnimation(const RefPtr<FrameNode>& menu, bool isInSubWindow = false); 301 void PopMenuAnimation(const RefPtr<FrameNode>& menu); 302 303 void OpenDialogAnimation(const RefPtr<FrameNode>& node); 304 void CloseDialogAnimation(const RefPtr<FrameNode>& node); 305 void SetContainerButtonEnable(bool isEnabled); 306 307 void SaveLastModalNode(); 308 void PlayDefaultModalTransition(const RefPtr<FrameNode>& modalNode, bool isTransitionIn); 309 void DefaultModalTransition(bool isTransitionIn); 310 void PlayAlphaModalTransition(const RefPtr<FrameNode>& modalNode, bool isTransitionIn); 311 void FireModalPageShow(); 312 void FireModalPageHide(); 313 void ModalPageLostFocus(const RefPtr<FrameNode>& node); 314 315 void PlaySheetTransition(RefPtr<FrameNode> sheetNode, bool isTransitionIn, bool isFirstTransition = true, 316 bool isModeChangeToAuto = false); 317 318 void ComputeSheetOffset(NG::SheetStyle& sheetStyle, RefPtr<FrameNode> sheetNode); 319 bool ModalExitProcess(const RefPtr<FrameNode>& topModalNode); 320 321 void BeforeShowDialog(const RefPtr<FrameNode>& dialogNode); 322 void RemoveDialogFromMap(const RefPtr<FrameNode>& node); 323 bool DialogInMapHoldingFocus(); 324 void PlayKeyboardTransition(RefPtr<FrameNode> customKeyboard, bool isTransitionIn); 325 326 // Key: target Id, Value: PopupInfo 327 std::unordered_map<int32_t, NG::PopupInfo> popupMap_; 328 // K: target frameNode ID, V: menuNode 329 std::unordered_map<int32_t, RefPtr<FrameNode>> menuMap_; 330 std::unordered_map<int32_t, RefPtr<FrameNode>> dialogMap_; 331 std::unordered_map<int32_t, RefPtr<FrameNode>> customPopupMap_; 332 std::unordered_map<int32_t, RefPtr<FrameNode>> customKeyboardMap_; 333 std::stack<WeakPtr<FrameNode>> modalStack_; 334 std::list<WeakPtr<FrameNode>> modalList_; 335 WeakPtr<FrameNode> lastModalNode_; 336 float sheetHeight_ {0.0}; 337 WeakPtr<UINode> rootNodeWeak_; 338 int32_t dialogCount_ = 0; 339 #ifdef ENABLE_DRAG_FRAMEWORK 340 bool hasPixelMap_ {false}; 341 bool hasFilter_ {false}; 342 bool hasEvent_ {false}; 343 bool isOnAnimation_ {false}; 344 WeakPtr<FrameNode> pixmapColumnNodeWeak_; 345 WeakPtr<FrameNode> filterColumnNodeWeak_; 346 WeakPtr<FrameNode> eventColumnNodeWeak_; 347 #endif // ENABLE_DRAG_FRAMEWORK 348 349 std::function<void()> onHideMenuCallback_ = nullptr; 350 std::function<void()> onHideDialogCallback_ = nullptr; 351 std::function<void()> onShowMenuCallback_; 352 CancelableCallback<void()> continuousTask_; 353 std::function<bool()> backPressEvent_ = nullptr; 354 355 std::set<WeakPtr<UINode>> windowSceneSet_; 356 357 ACE_DISALLOW_COPY_AND_MOVE(OverlayManager); 358 }; 359 } // namespace OHOS::Ace::NG 360 361 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_OVERLAY_OVERLAY_MANAGER_H 362