• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2025 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_DIALOG_DIALOG_PATTERN_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_DIALOG_DIALOG_PATTERN_H
18 
19 #include <cstdint>
20 #include <functional>
21 
22 #include "base/geometry/ng/offset_t.h"
23 #include "base/geometry/ng/size_t.h"
24 #include "base/memory/ace_type.h"
25 #include "base/memory/referenced.h"
26 #include "core/common/autofill/auto_fill_trigger_state_holder.h"
27 #include "core/components/dialog/dialog_properties.h"
28 #include "core/components/dialog/dialog_theme.h"
29 #include "core/components_ng/manager/focus/focus_view.h"
30 #include "core/components_ng/pattern/dialog/dialog_event_hub.h"
31 #include "core/components_ng/pattern/dialog/dialog_accessibility_property.h"
32 #include "core/components_ng/pattern/dialog/dialog_layout_algorithm.h"
33 #include "core/components_ng/pattern/dialog/dialog_layout_property.h"
34 #include "core/components_ng/pattern/overlay/popup_base_pattern.h"
35 #include "core/components_ng/manager/avoid_info/avoid_info_manager.h"
36 
37 namespace OHOS::Ace::NG {
38 class InspectorFilter;
39 
40 enum class DialogContentNode {
41     TITLE = 0,
42     SUBTITLE,
43     MESSAGE,
44     SHEET,
45     BORDERWIDTH,
46 };
47 enum class DialogDismissReason {
48     DIALOG_PRESS_BACK = 0,
49     DIALOG_TOUCH_OUTSIDE,
50     DIALOG_CLOSE_BUTTON,
51 };
52 class DialogPattern : public PopupBasePattern,
53                       public FocusView,
54                       public AutoFillTriggerStateHolder,
55                       public IAvoidInfoListener {
56     DECLARE_ACE_TYPE(DialogPattern, PopupBasePattern, FocusView,
57         AutoFillTriggerStateHolder, IAvoidInfoListener);
58 
59 public:
DialogPattern(const RefPtr<DialogTheme> & dialogTheme,const RefPtr<UINode> & customNode)60     DialogPattern(const RefPtr<DialogTheme>& dialogTheme, const RefPtr<UINode>& customNode)
61         : dialogTheme_(dialogTheme), customNode_(customNode)
62     {}
63     ~DialogPattern() override = default;
64 
IsAtomicNode()65     bool IsAtomicNode() const override
66     {
67         return false;
68     }
69 
SetOnWillDismiss(const std::function<void (const int32_t & info,const int32_t & instanceId)> & onWillDismiss)70     void SetOnWillDismiss(const std::function<void(const int32_t& info, const int32_t& instanceId)>& onWillDismiss)
71     {
72         onWillDismiss_ = onWillDismiss;
73     }
74 
SetOnWillDismissRelease(const std::function<void ()> & onWillDismissRelease)75     void SetOnWillDismissRelease(const std::function<void()>& onWillDismissRelease)
76     {
77         onWillDismissRelease_ = onWillDismissRelease;
78     }
79 
ShouldDismiss()80     bool ShouldDismiss() const
81     {
82         if (onWillDismiss_ && !isDialogDisposed_) {
83             return true;
84         }
85         return false;
86     }
87 
SetOnWillDismissByNDK(const std::function<bool (const int32_t & info)> & onWillDismissByNDK)88     void SetOnWillDismissByNDK(const std::function<bool(const int32_t& info)>& onWillDismissByNDK)
89     {
90         onWillDismissByNDK_ = onWillDismissByNDK;
91     }
92 
CallDismissInNDK(int reason)93     bool CallDismissInNDK(int reason)
94     {
95         if (onWillDismissByNDK_ && onWillDismissByNDK_(reason)) {
96             return true;
97         }
98         return false;
99     }
100 
CallOnWillDismiss(const int32_t reason,const int32_t instanceId)101     void CallOnWillDismiss(const int32_t reason, const int32_t instanceId)
102     {
103         if (onWillDismiss_ && !isDialogDisposed_) {
104             onWillDismiss_(reason, instanceId);
105         }
106     }
107 
CreateLayoutProperty()108     RefPtr<LayoutProperty> CreateLayoutProperty() override
109     {
110         return AceType::MakeRefPtr<DialogLayoutProperty>();
111     }
112 
113     RefPtr<LayoutAlgorithm> CreateLayoutAlgorithm() override;
114 
CreateEventHub()115     RefPtr<EventHub> CreateEventHub() override
116     {
117         return MakeRefPtr<DialogEventHub>();
118     }
119 
CreateAccessibilityProperty()120     RefPtr<AccessibilityProperty> CreateAccessibilityProperty() override
121     {
122         return MakeRefPtr<DialogAccessibilityProperty>();
123     }
124 
GetFocusPattern()125     FocusPattern GetFocusPattern() const override
126     {
127         return { FocusType::SCOPE, true };
128     }
129 
GetRouteOfFirstScope()130     std::list<int32_t> GetRouteOfFirstScope() override
131     {
132         if (dialogProperties_.type == DialogType::ALERT_DIALOG || dialogProperties_.type == DialogType::ACTION_SHEET) {
133             return { 0 };
134         }
135         return { 0, 0 };
136     }
137 
138     void BuildChild(const DialogProperties& dialogProperties);
139 
140     void ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const override;
141 
GetTitle()142     const std::string& GetTitle()
143     {
144         return title_;
145     }
146 
GetSubtitle()147     const std::string& GetSubtitle()
148     {
149         return subtitle_;
150     }
151 
GetMessage()152     const std::string& GetMessage()
153     {
154         return message_;
155     }
156 
GetCustomNode()157     RefPtr<UINode> GetCustomNode()
158     {
159         return customNode_.Upgrade();
160     }
161 
SetOpenAnimation(const std::optional<AnimationOption> & openAnimation)162     void SetOpenAnimation(const std::optional<AnimationOption>& openAnimation)
163     {
164         openAnimation_ = openAnimation;
165     }
GetOpenAnimation()166     std::optional<AnimationOption> GetOpenAnimation() const
167     {
168         return openAnimation_;
169     }
170 
SetCloseAnimation(const std::optional<AnimationOption> & closeAnimation)171     void SetCloseAnimation(const std::optional<AnimationOption>& closeAnimation)
172     {
173         closeAnimation_ = closeAnimation;
174     }
GetCloseAnimation()175     std::optional<AnimationOption> GetCloseAnimation() const
176     {
177         return closeAnimation_;
178     }
179 
SetDialogProperties(const DialogProperties & param)180     void SetDialogProperties(const DialogProperties& param)
181     {
182         dialogProperties_ = param;
183         InitHostWindowRect();
184     }
185 
186     bool GetWindowButtonRect(NG::RectF& floatButtons);
187 
GetDialogProperties()188     const DialogProperties& GetDialogProperties() const
189     {
190         return dialogProperties_;
191     }
192 
193     void OnColorConfigurationUpdate() override;
194 
195     void OnLanguageConfigurationUpdate() override;
196 
197     void DumpInfo() override;
198     void DumpInfo(std::unique_ptr<JsonValue>& json) override;
AvoidBottom()199     bool AvoidBottom() const override
200     {
201         return false;
202     }
203 
RegisterDialogDidAppearCallback(std::function<void ()> && onDidAppear)204     void RegisterDialogDidAppearCallback(std::function<void()>&& onDidAppear)
205     {
206         onDidAppearCallback_ = std::move(onDidAppear);
207     }
208 
RegisterDialogDidDisappearCallback(std::function<void ()> && onDidDisappear)209     void RegisterDialogDidDisappearCallback(std::function<void()>&& onDidDisappear)
210     {
211         onDidDisappearCallback_ = std::move(onDidDisappear);
212     }
213 
RegisterDialogWillAppearCallback(std::function<void ()> && onWillAppear)214     void RegisterDialogWillAppearCallback(std::function<void()>&& onWillAppear)
215     {
216         onWillAppearCallback_ = std::move(onWillAppear);
217     }
218 
RegisterDialogWillDisappearCallback(std::function<void ()> && onWillDisappear)219     void RegisterDialogWillDisappearCallback(std::function<void()>&& onWillDisappear)
220     {
221         onWillDisappearCallback_ = std::move(onWillDisappear);
222     }
223 
CallDialogDidAppearCallback()224     void CallDialogDidAppearCallback()
225     {
226         if (onDidAppearCallback_) {
227             onDidAppearCallback_();
228         }
229         SetState(PromptActionCommonState::APPEARED);
230         TAG_LOGI(AceLogTag::ACE_DIALOG, "The current state of the dialog is APPEARED.");
231     }
232 
CallDialogDidDisappearCallback()233     void CallDialogDidDisappearCallback()
234     {
235         if (onDidDisappearCallback_) {
236             onDidDisappearCallback_();
237         }
238         SetState(PromptActionCommonState::DISAPPEARED);
239         TAG_LOGI(AceLogTag::ACE_DIALOG, "The current state of the dialog is DISAPPEARED.");
240     }
241 
CallDialogWillAppearCallback()242     void CallDialogWillAppearCallback()
243     {
244         if (onWillAppearCallback_) {
245             onWillAppearCallback_();
246         }
247         SetState(PromptActionCommonState::APPEARING);
248         TAG_LOGI(AceLogTag::ACE_DIALOG, "The current state of the dialog is APPEARING.");
249     }
250 
CallDialogWillDisappearCallback()251     void CallDialogWillDisappearCallback()
252     {
253         if (onWillDisappearCallback_) {
254             onWillDisappearCallback_();
255         }
256         SetState(PromptActionCommonState::DISAPPEARING);
257         TAG_LOGI(AceLogTag::ACE_DIALOG, "The current state of the dialog is DISAPPEARING.");
258     }
259 
IsUIExtensionSubWindow()260     bool IsUIExtensionSubWindow() const
261     {
262         return isUIExtensionSubWindow_;
263     }
264 
GetHostWindowRect()265     RectF GetHostWindowRect() const
266     {
267         return hostWindowRect_;
268     }
269 
UpdateFoldDisplayModeChangedCallbackId(std::optional<int32_t> id)270     void UpdateFoldDisplayModeChangedCallbackId(std::optional<int32_t> id)
271     {
272         foldDisplayModeChangedCallbackId_ = id;
273     }
274 
HasFoldDisplayModeChangedCallbackId()275     bool HasFoldDisplayModeChangedCallbackId()
276     {
277         return foldDisplayModeChangedCallbackId_.has_value();
278     }
279 
UpdateHoverModeChangedCallbackId(std::optional<int32_t> id)280     void UpdateHoverModeChangedCallbackId(std::optional<int32_t> id)
281     {
282         hoverModeChangedCallbackId_ = id;
283     }
284 
HasHoverModeChangedCallbackId()285     bool HasHoverModeChangedCallbackId()
286     {
287         return hoverModeChangedCallbackId_.has_value();
288     }
289 
GetIsSuitableForAging()290     bool GetIsSuitableForAging()
291     {
292         return isSuitableForElderly_;
293     }
294 
GetFontScaleForElderly()295     float GetFontScaleForElderly()
296     {
297         return fontScaleForElderly_;
298     }
299 
SetIsPickerDialog(bool value)300     void SetIsPickerDialog(bool value)
301     {
302         isPickerDialog_ = value;
303     }
304 
GetIsPickerDialog()305     bool GetIsPickerDialog()
306     {
307         return isPickerDialog_;
308     }
309 
310     void UpdateDeviceOrientation(const DeviceOrientation& deviceOrientation);
311     void InitHostWindowRect();
312     void UpdateHostWindowRect();
313     void UpdateFontScale();
314 
GetIsSuitOldMeasure()315     bool GetIsSuitOldMeasure()
316     {
317         return isSuitOldMeasure_;
318     }
319 
SetIsScrollHeightNegative(bool isScrollHeightNegative)320     void SetIsScrollHeightNegative(bool isScrollHeightNegative)
321     {
322         isScrollHeightNegative_ = isScrollHeightNegative;
323     }
324 
TriggerAutoSaveWhenInvisible()325     bool TriggerAutoSaveWhenInvisible() override
326     {
327         return true;
328     }
329 
SetIsDialogDisposed(bool isDialogDisposed)330     void SetIsDialogDisposed(bool isDialogDisposed)
331     {
332         isDialogDisposed_ = isDialogDisposed;
333     }
334 
SetState(PromptActionCommonState value)335     void SetState(PromptActionCommonState value)
336     {
337         state = value;
338     }
339 
GetState()340     PromptActionCommonState GetState()
341     {
342         return state;
343     }
344 
345     bool IsShowInFreeMultiWindow();
346     bool IsShowInFloatingWindow();
347     void AddExtraMaskNode(const DialogProperties& props);
348 
getTransitionNodeCount()349     int32_t getTransitionNodeCount()
350     {
351         return transitionNodeCount_;
352     }
353 
addTransitionNodeCount()354     void addTransitionNodeCount()
355     {
356         transitionNodeCount_++;
357     }
358 
359     void OverlayDismissDialog(const RefPtr<FrameNode>& dialogNode);
360     RefPtr<OverlayManager> GetEmbeddedOverlay(const RefPtr<OverlayManager>& context);
361 
362 private:
AvoidKeyboard()363     bool AvoidKeyboard() const override
364     {
365         return false;
366     }
367     void OnModifyDone() override;
368 
369     void OnAttachToFrameNode() override;
370     void OnDetachFromFrameNode(FrameNode* frameNode) override;
371     void RegisterHoverModeChangeCallback();
372     void OnWindowSizeChanged(int32_t width, int32_t height, WindowSizeChangeReason type) override;
373     void InitClickEvent(const RefPtr<GestureEventHub>& gestureHub);
374     RectF GetContentRect(const RefPtr<FrameNode>& contentNode);
375     void HandleClick(const GestureEvent& info);
376     void RegisterOnKeyEvent(const RefPtr<FocusHub>& focusHub);
377     bool OnKeyEvent(const KeyEvent& event);
378     void InitFocusEvent(const RefPtr<FocusHub>& focusHub);
379     void HandleBlurEvent();
380     void HandleFocusEvent();
381     void OnAvoidInfoChange(const ContainerModalAvoidInfo& info) override;
382     void RegisterAvoidInfoChangeListener(const RefPtr<FrameNode>& hostNode);
383     void UnRegisterAvoidInfoChangeListener(FrameNode* hostNode);
384 
385     void PopDialog(int32_t buttonIdx);
386     bool NeedUpdateHostWindowRect();
387 
388     // set render context properties of content frame
389     void UpdateContentRenderContext(const RefPtr<FrameNode>& contentNode, const DialogProperties& props);
390     void BuildCustomChild(const DialogProperties& props, const RefPtr<UINode>& customNode);
391     RefPtr<FrameNode> BuildMainTitle(const DialogProperties& dialogProperties);
392     RefPtr<FrameNode> BuildSubTitle(const DialogProperties& dialogProperties);
393     void ParseButtonFontColorAndBgColor(
394         const ButtonInfo& params, std::string& textColor, std::optional<Color>& bgColor);
395     void SetButtonEnabled(const RefPtr<FrameNode>& buttonNode, bool enabled);
396     // update wrapperNode background style
397     void UpdateWrapperBackgroundStyle(const RefPtr<FrameNode>& host, const RefPtr<DialogTheme>& dialogTheme);
398     RefPtr<FrameNode> BuildTitle(const DialogProperties& dialogProperties);
399     RefPtr<FrameNode> BuildContent(const DialogProperties& dialogProperties);
400     RefPtr<FrameNode> CreateDialogScroll(const DialogProperties& dialogProps);
401 
402     void UpdateDialogButtonProperty(RefPtr<FrameNode>& buttonNode, int32_t index, bool isVertical, int32_t length);
403     RefPtr<FrameNode> BuildButtons(const std::vector<ButtonInfo>& buttons, const DialogButtonDirection& direction);
404     void AddButtonAndDivider(
405         const std::vector<ButtonInfo>& buttons, const RefPtr<NG::FrameNode>& container, bool isVertical);
406     RefPtr<FrameNode> CreateDivider(
407         const Dimension& dividerLength, const Dimension& dividerWidth, const Color& color, const Dimension& space);
408     RefPtr<FrameNode> CreateButton(
409         const ButtonInfo& params, int32_t index, bool isCancel = false, bool isVertical = false, int32_t length = 0);
410     RefPtr<FrameNode> CreateButtonText(const std::string& text, const std::string& colorStr);
411     // to close dialog when button is clicked
412     void BindCloseCallBack(const RefPtr<GestureEventHub>& hub, int32_t buttonIdx);
413     // build ActionSheet items
414     RefPtr<FrameNode> BuildSheet(const std::vector<ActionSheetInfo>& sheets);
415     RefPtr<FrameNode> BuildSheetItem(const ActionSheetInfo& item);
416     RefPtr<FrameNode> BuildSheetInfoTitle(const std::string& title);
417     RefPtr<FrameNode> BuildSheetInfoIcon(const std::string& icon);
418     // build actionMenu
419     RefPtr<FrameNode> BuildMenu(const std::vector<ButtonInfo>& buttons, bool hasTitle);
420     void RecordEvent(int32_t btnIndex) const;
421     void ParseBorderRadius(BorderRadiusProperty& raidus);
422     void UpdateSheetIconAndText();
423     void UpdateButtonsPropertyForEachButton(RefPtr<FrameNode> buttonFrameNode, int32_t btnindex);
424     void UpdateButtonsProperty();
425     void UpdateNodeContent(const RefPtr<FrameNode>& node, std::string& text);
426     void UpdateTitleAndContentColor();
427     void UpdateDialogTextColor(const RefPtr<FrameNode>& textNode, const TextStyle& textStyle);
428     void UpdateAlignmentAndOffset();
429     void DumpBoolProperty();
430     void DumpBoolProperty(std::unique_ptr<JsonValue>& json);
431     void DumpObjectProperty();
432     void DumpObjectProperty(std::unique_ptr<JsonValue>& json);
433     void DumpSimplifyBoolProperty(std::unique_ptr<JsonValue>& json);
434     void DumpSimplifyObjectProperty(std::unique_ptr<JsonValue>& json);
435     void DumpSimplifyBorderProperty(std::unique_ptr<JsonValue>& json);
436     void DumpSimplifySizeProperty(std::unique_ptr<JsonValue>& json);
437     void UpdatePropertyForElderly(const std::vector<ButtonInfo>& buttons);
438     bool NeedsButtonDirectionChange(const std::vector<ButtonInfo>& buttons);
439     void OnFontConfigurationUpdate() override;
440     void UpdateTextFontScale();
441     void UpdateTitleTextFontScale();
442     void CheckScrollHeightIsNegative(const RefPtr<UINode>& contentColumn, const DialogProperties& props);
443     RefPtr<OverlayManager> GetOverlayManager(const RefPtr<FrameNode>& host);
444     void OnAttachToMainTree() override;
445     void OnDetachFromMainTree() override;
446     void AddFollowParentWindowLayoutNode();
447     void RemoveFollowParentWindowLayoutNode();
448     void RegisterButtonOnKeyEvent(const ButtonInfo& params, RefPtr<FrameNode>& buttonNode, int32_t buttonIdx);
449     RefPtr<DialogTheme> dialogTheme_;
450     WeakPtr<UINode> customNode_;
451     RefPtr<ClickEvent> onClick_;
452 
453     std::optional<AnimationOption> openAnimation_;
454     std::optional<AnimationOption> closeAnimation_;
455     std::optional<int32_t> foldDisplayModeChangedCallbackId_;
456     std::optional<int32_t> hoverModeChangedCallbackId_;
457     bool isFoldStatusChanged_ = false;
458 
459     // XTS inspector values
460     std::string message_;
461     std::string title_;
462     std::string subtitle_;
463     std::function<void(const int32_t& info, const int32_t& instanceId)> onWillDismiss_;
464     std::function<void()> onWillDismissRelease_;
465     std::function<bool(const int32_t& info)> onWillDismissByNDK_;
466 
467     DialogProperties dialogProperties_;
468     WeakPtr<FrameNode> menuNode_;
469     bool isFirstDefaultFocus_ = true;
470     RefPtr<FrameNode> buttonContainer_;
471     RefPtr<FrameNode> contentColumn_;
472     RefPtr<RenderContext> contentRenderContext_;
473     bool isSuitableForElderly_ = false;
474     bool isPickerDialog_ = false;
475     bool notAdapationAging_ = false;
476     bool isSuitOldMeasure_ = false;
477     bool isScrollHeightNegative_ = false;
478     float fontScaleForElderly_ = 1.0f;
479     PromptActionCommonState state = PromptActionCommonState::UNINITIALIZED;
480     DeviceOrientation deviceOrientation_ = DeviceOrientation::PORTRAIT;
481     RefPtr<FrameNode> titleContainer_;
482     int32_t transitionNodeCount_ = 0;
483 
484     ACE_DISALLOW_COPY_AND_MOVE(DialogPattern);
485 
486     std::function<void()> onDidAppearCallback_ = nullptr;
487     std::function<void()> onDidDisappearCallback_ = nullptr;
488     std::function<void()> onWillAppearCallback_ = nullptr;
489     std::function<void()> onWillDisappearCallback_ = nullptr;
490     std::unordered_map<DialogContentNode, RefPtr<FrameNode>> contentNodeMap_;
491     bool isUIExtensionSubWindow_ = false;
492     bool isDialogDisposed_ = false;
493     RectF hostWindowRect_;
494 };
495 } // namespace OHOS::Ace::NG
496 
497 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_DIALOG_DIALOG_PATTERN_H
498