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_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 36 namespace OHOS::Ace::NG { 37 class InspectorFilter; 38 39 enum class DialogContentNode { 40 TITLE = 0, 41 SUBTITLE, 42 MESSAGE, 43 SHEET, 44 BORDERWIDTH, 45 }; 46 enum class DialogDismissReason { 47 DIALOG_PRESS_BACK = 0, 48 DIALOG_TOUCH_OUTSIDE, 49 DIALOG_CLOSE_BUTTON, 50 }; 51 class DialogPattern : public PopupBasePattern, public FocusView, public AutoFillTriggerStateHolder { 52 DECLARE_ACE_TYPE(DialogPattern, PopupBasePattern, FocusView, AutoFillTriggerStateHolder); 53 54 public: DialogPattern(const RefPtr<DialogTheme> & dialogTheme,const RefPtr<UINode> & customNode)55 DialogPattern(const RefPtr<DialogTheme>& dialogTheme, const RefPtr<UINode>& customNode) 56 : dialogTheme_(dialogTheme), customNode_(customNode) 57 {} 58 ~DialogPattern() override = default; 59 IsAtomicNode()60 bool IsAtomicNode() const override 61 { 62 return false; 63 } 64 SetOnWillDismiss(const std::function<void (const int32_t & info)> & onWillDismiss)65 void SetOnWillDismiss(const std::function<void(const int32_t& info)>& onWillDismiss) 66 { 67 onWillDismiss_ = onWillDismiss; 68 } 69 ShouldDismiss()70 bool ShouldDismiss() const 71 { 72 if (onWillDismiss_) { 73 return true; 74 } 75 return false; 76 } 77 SetOnWillDismissByNDK(const std::function<bool (const int32_t & info)> & onWillDismissByNDK)78 void SetOnWillDismissByNDK(const std::function<bool(const int32_t& info)>& onWillDismissByNDK) 79 { 80 onWillDismissByNDK_ = onWillDismissByNDK; 81 } 82 CallDismissInNDK(int reason)83 bool CallDismissInNDK(int reason) 84 { 85 if (onWillDismissByNDK_ && onWillDismissByNDK_(reason)) { 86 return true; 87 } 88 return false; 89 } 90 CallOnWillDismiss(const int32_t reason)91 void CallOnWillDismiss(const int32_t reason) 92 { 93 if (onWillDismiss_) { 94 onWillDismiss_(reason); 95 } 96 } 97 CreateLayoutProperty()98 RefPtr<LayoutProperty> CreateLayoutProperty() override 99 { 100 return AceType::MakeRefPtr<DialogLayoutProperty>(); 101 } 102 CreateLayoutAlgorithm()103 RefPtr<LayoutAlgorithm> CreateLayoutAlgorithm() override 104 { 105 return AceType::MakeRefPtr<DialogLayoutAlgorithm>(); 106 } 107 CreateEventHub()108 RefPtr<EventHub> CreateEventHub() override 109 { 110 return MakeRefPtr<DialogEventHub>(); 111 } 112 CreateAccessibilityProperty()113 RefPtr<AccessibilityProperty> CreateAccessibilityProperty() override 114 { 115 return MakeRefPtr<DialogAccessibilityProperty>(); 116 } 117 GetFocusPattern()118 FocusPattern GetFocusPattern() const override 119 { 120 return { FocusType::SCOPE, true }; 121 } 122 GetRouteOfFirstScope()123 std::list<int32_t> GetRouteOfFirstScope() override 124 { 125 if (dialogProperties_.type == DialogType::ALERT_DIALOG || dialogProperties_.type == DialogType::ACTION_SHEET) { 126 return { 0 }; 127 } 128 return { 0, 0 }; 129 } 130 131 void BuildChild(const DialogProperties& dialogProperties); 132 133 void ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const override; 134 GetTitle()135 const std::string& GetTitle() 136 { 137 return title_; 138 } 139 GetSubtitle()140 const std::string& GetSubtitle() 141 { 142 return subtitle_; 143 } 144 GetMessage()145 const std::string& GetMessage() 146 { 147 return message_; 148 } 149 GetCustomNode()150 RefPtr<UINode> GetCustomNode() 151 { 152 return customNode_.Upgrade(); 153 } 154 SetOpenAnimation(const std::optional<AnimationOption> & openAnimation)155 void SetOpenAnimation(const std::optional<AnimationOption>& openAnimation) 156 { 157 openAnimation_ = openAnimation; 158 } GetOpenAnimation()159 std::optional<AnimationOption> GetOpenAnimation() const 160 { 161 return openAnimation_; 162 } 163 SetCloseAnimation(const std::optional<AnimationOption> & closeAnimation)164 void SetCloseAnimation(const std::optional<AnimationOption>& closeAnimation) 165 { 166 closeAnimation_ = closeAnimation; 167 } GetCloseAnimation()168 std::optional<AnimationOption> GetCloseAnimation() const 169 { 170 return closeAnimation_; 171 } 172 SetDialogProperties(const DialogProperties & param)173 void SetDialogProperties(const DialogProperties& param) 174 { 175 dialogProperties_ = param; 176 InitHostWindowRect(); 177 } 178 GetDialogProperties()179 const DialogProperties& GetDialogProperties() const 180 { 181 return dialogProperties_; 182 } 183 184 void OnColorConfigurationUpdate() override; 185 186 void OnLanguageConfigurationUpdate() override; 187 188 void DumpInfo() override; 189 void DumpSimplifyInfo(std::unique_ptr<JsonValue>& json) override; AvoidBottom()190 bool AvoidBottom() const override 191 { 192 return false; 193 } 194 RegisterDialogDidAppearCallback(std::function<void ()> && onDidAppear)195 void RegisterDialogDidAppearCallback(std::function<void()>&& onDidAppear) 196 { 197 onDidAppearCallback_ = std::move(onDidAppear); 198 } 199 RegisterDialogDidDisappearCallback(std::function<void ()> && onDidDisappear)200 void RegisterDialogDidDisappearCallback(std::function<void()>&& onDidDisappear) 201 { 202 onDidDisappearCallback_ = std::move(onDidDisappear); 203 } 204 RegisterDialogWillAppearCallback(std::function<void ()> && onWillAppear)205 void RegisterDialogWillAppearCallback(std::function<void()>&& onWillAppear) 206 { 207 onWillAppearCallback_ = std::move(onWillAppear); 208 } 209 RegisterDialogWillDisappearCallback(std::function<void ()> && onWillDisappear)210 void RegisterDialogWillDisappearCallback(std::function<void()>&& onWillDisappear) 211 { 212 onWillDisappearCallback_ = std::move(onWillDisappear); 213 } 214 CallDialogDidAppearCallback()215 void CallDialogDidAppearCallback() 216 { 217 if (onDidAppearCallback_) { 218 onDidAppearCallback_(); 219 } 220 } 221 CallDialogDidDisappearCallback()222 void CallDialogDidDisappearCallback() 223 { 224 if (onDidDisappearCallback_) { 225 onDidDisappearCallback_(); 226 } 227 } 228 CallDialogWillAppearCallback()229 void CallDialogWillAppearCallback() 230 { 231 if (onWillAppearCallback_) { 232 onWillAppearCallback_(); 233 } 234 } 235 CallDialogWillDisappearCallback()236 void CallDialogWillDisappearCallback() 237 { 238 if (onWillDisappearCallback_) { 239 onWillDisappearCallback_(); 240 } 241 } 242 IsUIExtensionSubWindow()243 bool IsUIExtensionSubWindow() const 244 { 245 return isUIExtensionSubWindow_; 246 } 247 GetHostWindowRect()248 RectF GetHostWindowRect() const 249 { 250 return hostWindowRect_; 251 } 252 UpdateFoldDisplayModeChangedCallbackId(std::optional<int32_t> id)253 void UpdateFoldDisplayModeChangedCallbackId(std::optional<int32_t> id) 254 { 255 foldDisplayModeChangedCallbackId_ = id; 256 } 257 HasFoldDisplayModeChangedCallbackId()258 bool HasFoldDisplayModeChangedCallbackId() 259 { 260 return foldDisplayModeChangedCallbackId_.has_value(); 261 } 262 UpdateHoverModeChangedCallbackId(std::optional<int32_t> id)263 void UpdateHoverModeChangedCallbackId(std::optional<int32_t> id) 264 { 265 hoverModeChangedCallbackId_ = id; 266 } 267 HasHoverModeChangedCallbackId()268 bool HasHoverModeChangedCallbackId() 269 { 270 return hoverModeChangedCallbackId_.has_value(); 271 } 272 GetIsSuitableForAging()273 bool GetIsSuitableForAging() 274 { 275 return isSuitableForElderly_; 276 } 277 GetFontScaleForElderly()278 float GetFontScaleForElderly() 279 { 280 return fontScaleForElderly_; 281 } 282 SetIsPickerDialog(bool value)283 void SetIsPickerDialog(bool value) 284 { 285 isPickerDialog_ = value; 286 } 287 GetIsPickerDialog()288 bool GetIsPickerDialog() 289 { 290 return isPickerDialog_; 291 } 292 293 void UpdateDeviceOrientation(const DeviceOrientation& deviceOrientation); 294 void InitHostWindowRect(); 295 void UpdateFontScale(); 296 PipelineContext* GetDialogContext(); 297 GetIsSuitOldMeasure()298 bool GetIsSuitOldMeasure() 299 { 300 return isSuitOldMeasure_; 301 } 302 SetIsScrollHeightNegative(bool isScrollHeightNegative)303 void SetIsScrollHeightNegative(bool isScrollHeightNegative) 304 { 305 isScrollHeightNegative_ = isScrollHeightNegative; 306 } 307 TriggerAutoSaveWhenInvisible()308 bool TriggerAutoSaveWhenInvisible() override 309 { 310 return true; 311 } 312 313 bool IsShowInFreeMultiWindow(); 314 315 private: AvoidKeyboard()316 bool AvoidKeyboard() const override 317 { 318 return false; 319 } 320 void OnModifyDone() override; 321 322 void OnAttachToFrameNode() override; 323 void OnDetachFromFrameNode(FrameNode* frameNode) override; 324 void RegisterHoverModeChangeCallback(); 325 void OnWindowSizeChanged(int32_t width, int32_t height, WindowSizeChangeReason type) override; 326 void InitClickEvent(const RefPtr<GestureEventHub>& gestureHub); 327 void HandleClick(const GestureEvent& info); 328 void RegisterOnKeyEvent(const RefPtr<FocusHub>& focusHub); 329 bool OnKeyEvent(const KeyEvent& event); 330 void InitFocusEvent(const RefPtr<FocusHub>& focusHub); 331 void HandleBlurEvent(); 332 void HandleFocusEvent(); 333 334 void PopDialog(int32_t buttonIdx); 335 336 // set render context properties of content frame 337 void UpdateContentRenderContext(const RefPtr<FrameNode>& contentNode, const DialogProperties& props); 338 void BuildCustomChild(const DialogProperties& props, const RefPtr<UINode>& customNode); 339 RefPtr<FrameNode> BuildMainTitle(const DialogProperties& dialogProperties); 340 RefPtr<FrameNode> BuildSubTitle(const DialogProperties& dialogProperties); 341 void ParseButtonFontColorAndBgColor( 342 const ButtonInfo& params, std::string& textColor, std::optional<Color>& bgColor); 343 void SetButtonEnabled(const RefPtr<FrameNode>& buttonNode, bool enabled); 344 // update wrapperNode background style 345 void UpdateWrapperBackgroundStyle(const RefPtr<FrameNode>& host, const RefPtr<DialogTheme>& dialogTheme); 346 RefPtr<FrameNode> BuildTitle(const DialogProperties& dialogProperties); 347 RefPtr<FrameNode> BuildContent(const DialogProperties& dialogProperties); 348 RefPtr<FrameNode> CreateDialogScroll(const DialogProperties& dialogProps); 349 350 void UpdateDialogButtonProperty(RefPtr<FrameNode>& buttonNode, int32_t index, bool isVertical, int32_t length); 351 RefPtr<FrameNode> BuildButtons(const std::vector<ButtonInfo>& buttons, const DialogButtonDirection& direction); 352 void AddButtonAndDivider( 353 const std::vector<ButtonInfo>& buttons, const RefPtr<NG::FrameNode>& container, bool isVertical); 354 RefPtr<FrameNode> CreateDivider( 355 const Dimension& dividerLength, const Dimension& dividerWidth, const Color& color, const Dimension& space); 356 RefPtr<FrameNode> CreateButton( 357 const ButtonInfo& params, int32_t index, bool isCancel = false, bool isVertical = false, int32_t length = 0); 358 RefPtr<FrameNode> CreateButtonText(const std::string& text, const std::string& colorStr); 359 // to close dialog when button is clicked 360 void BindCloseCallBack(const RefPtr<GestureEventHub>& hub, int32_t buttonIdx); 361 // build ActionSheet items 362 RefPtr<FrameNode> BuildSheet(const std::vector<ActionSheetInfo>& sheets); 363 RefPtr<FrameNode> BuildSheetItem(const ActionSheetInfo& item); 364 RefPtr<FrameNode> BuildSheetInfoTitle(const std::string& title); 365 RefPtr<FrameNode> BuildSheetInfoIcon(const std::string& icon); 366 // build actionMenu 367 RefPtr<FrameNode> BuildMenu(const std::vector<ButtonInfo>& buttons, bool hasTitle); 368 void RecordEvent(int32_t btnIndex) const; 369 void ParseBorderRadius(BorderRadiusProperty& raidus); 370 void UpdateSheetIconAndText(); 371 void UpdateButtonsProperty(); 372 void UpdateNodeContent(const RefPtr<FrameNode>& node, std::string& text); 373 void UpdateAlignmentAndOffset(); 374 void DumpBoolProperty(); 375 void DumpObjectProperty(); 376 void DumpSimplifyBoolProperty(std::unique_ptr<JsonValue>& json); 377 void DumpSimplifyObjectProperty(std::unique_ptr<JsonValue>& json); 378 void DumpSimplifyBorderProperty(std::unique_ptr<JsonValue>& json); 379 void DumpSimplifySizeProperty(std::unique_ptr<JsonValue>& json); 380 void UpdatePropertyForElderly(const std::vector<ButtonInfo>& buttons); 381 bool NeedsButtonDirectionChange(const std::vector<ButtonInfo>& buttons); 382 void OnFontConfigurationUpdate() override; 383 void UpdateTextFontScale(); 384 void UpdateTitleTextFontScale(); 385 void CheckScrollHeightIsNegative(const RefPtr<UINode>& contentColumn, const DialogProperties& props); 386 RefPtr<DialogTheme> dialogTheme_; 387 WeakPtr<UINode> customNode_; 388 RefPtr<ClickEvent> onClick_; 389 390 std::optional<AnimationOption> openAnimation_; 391 std::optional<AnimationOption> closeAnimation_; 392 std::optional<int32_t> foldDisplayModeChangedCallbackId_; 393 std::optional<int32_t> hoverModeChangedCallbackId_; 394 bool isFoldStatusChanged_ = false; 395 396 // XTS inspector values 397 std::string message_; 398 std::string title_; 399 std::string subtitle_; 400 std::function<void(const int32_t& info)> onWillDismiss_; 401 std::function<bool(const int32_t& info)> onWillDismissByNDK_; 402 403 DialogProperties dialogProperties_; 404 WeakPtr<FrameNode> menuNode_; 405 bool isFirstDefaultFocus_ = true; 406 RefPtr<FrameNode> buttonContainer_; 407 RefPtr<FrameNode> contentColumn_; 408 RefPtr<RenderContext> contentRenderContext_; 409 bool isSuitableForElderly_ = false; 410 bool isPickerDialog_ = false; 411 bool notAdapationAging_ = false; 412 bool isSuitOldMeasure_ = false; 413 bool isScrollHeightNegative_ = false; 414 float fontScaleForElderly_ = 1.0f; 415 DeviceOrientation deviceOrientation_ = DeviceOrientation::PORTRAIT; 416 RefPtr<FrameNode> titleContainer_; 417 418 ACE_DISALLOW_COPY_AND_MOVE(DialogPattern); 419 420 std::function<void()> onDidAppearCallback_ = nullptr; 421 std::function<void()> onDidDisappearCallback_ = nullptr; 422 std::function<void()> onWillAppearCallback_ = nullptr; 423 std::function<void()> onWillDisappearCallback_ = nullptr; 424 std::unordered_map<DialogContentNode, RefPtr<FrameNode>> contentNodeMap_; 425 bool isUIExtensionSubWindow_ = false; 426 RectF hostWindowRect_; 427 }; 428 } // namespace OHOS::Ace::NG 429 430 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_DIALOG_DIALOG_PATTERN_H 431