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