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