1 /* 2 * Copyright (c) 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_SHEET_PRESENTATION_PATTERN_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_OVERLAY_SHEET_PRESENTATION_PATTERN_H 18 19 #include <functional> 20 #include <utility> 21 22 #include "base/memory/ace_type.h" 23 #include "base/memory/referenced.h" 24 #include "core/components/common/properties/alignment.h" 25 #include "core/components_ng/pattern/linear_layout/linear_layout_algorithm.h" 26 #include "core/components_ng/pattern/linear_layout/linear_layout_pattern.h" 27 #include "core/components_ng/pattern/linear_layout/linear_layout_property.h" 28 #include "core/components_ng/pattern/overlay/popup_base_pattern.h" 29 #include "core/components_ng/pattern/overlay/sheet_presentation_layout_algorithm.h" 30 #include "core/components_ng/pattern/overlay/sheet_presentation_property.h" 31 #include "core/components_ng/pattern/overlay/sheet_style.h" 32 #include "core/pipeline_ng/pipeline_context.h" 33 34 namespace OHOS::Ace::NG { 35 class ACE_EXPORT SheetPresentationPattern : public LinearLayoutPattern, public PopupBasePattern { 36 DECLARE_ACE_TYPE(SheetPresentationPattern, LinearLayoutPattern, PopupBasePattern); 37 38 public: SheetPresentationPattern(int32_t targetId,const std::string & targetTag,std::function<void (const std::string &)> && callback)39 SheetPresentationPattern( 40 int32_t targetId, const std::string& targetTag, std::function<void(const std::string&)>&& callback) 41 : LinearLayoutPattern(true) 42 { 43 targetId_ = targetId; 44 targetTag_ = targetTag; 45 callback_ = std::move(callback); 46 } 47 48 ~SheetPresentationPattern() override = default; 49 IsMeasureBoundary()50 bool IsMeasureBoundary() const override 51 { 52 return true; 53 } 54 IsAtomicNode()55 bool IsAtomicNode() const override 56 { 57 return false; 58 } 59 CreateLayoutAlgorithm()60 RefPtr<LayoutAlgorithm> CreateLayoutAlgorithm() override 61 { 62 return MakeRefPtr<SheetPresentationLayoutAlgorithm>(targetId_, targetTag_, GetSheetType()); 63 } 64 CreateLayoutProperty()65 RefPtr<LayoutProperty> CreateLayoutProperty() override 66 { 67 return MakeRefPtr<SheetPresentationProperty>(); 68 } 69 GetTargetId()70 int32_t GetTargetId() const override 71 { 72 return targetId_; 73 } 74 FireCallback(const std::string & value)75 void FireCallback(const std::string& value) 76 { 77 if (callback_) { 78 callback_(value); 79 } 80 } 81 HasCallback()82 bool HasCallback() const 83 { 84 return static_cast<bool>(callback_); 85 } 86 UpdateShouldDismiss(std::function<void ()> && shouldDismiss)87 void UpdateShouldDismiss(std::function<void()>&& shouldDismiss) 88 { 89 shouldDismiss_ = std::move(shouldDismiss); 90 } 91 hasShouldDismiss()92 bool hasShouldDismiss() 93 { 94 if (shouldDismiss_) { 95 return true; 96 } 97 return false; 98 } 99 UpdateOnDisappear(std::function<void ()> && onDisappear)100 void UpdateOnDisappear(std::function<void()>&& onDisappear) 101 { 102 onDisappear_ = std::move(onDisappear); 103 isExecuteOnDisappear_ = false; 104 } 105 OnDisappear()106 void OnDisappear() 107 { 108 if (onDisappear_) { 109 isExecuteOnDisappear_ = true; 110 onDisappear_(); 111 } 112 } 113 CallShouldDismiss()114 void CallShouldDismiss() 115 { 116 if (shouldDismiss_) { 117 shouldDismiss_(); 118 } 119 } 120 DismissSheet()121 void DismissSheet() 122 { 123 DismissTransition(false); 124 } 125 126 void InitialLayoutProps(); 127 128 bool IsScrollable() const; 129 void AvoidAiBar(); 130 void AvoidSafeArea(); 131 float GetSheetHeightChange(); 132 void ScrollTo(float height); 133 float InitialSingleGearHeight(NG::SheetStyle& sheetStyle); 134 135 // initial drag gesture event 136 void InitPanEvent(); 137 138 void HandleDragStart(); 139 140 void HandleDragUpdate(const GestureEvent& info); 141 142 void HandleDragEnd(float dragVelocity); 143 144 void OnCoordScrollStart(); 145 146 bool OnCoordScrollUpdate(float scrollOffset); 147 148 void OnCoordScrollEnd(float dragVelocity); 149 150 void SheetTransition(bool isTransitionIn, float dragVelocity = 0.0f); 151 152 void SheetInteractiveDismiss(bool isDragClose, float dragVelocity = 0.0f); 153 SetCurrentOffset(float currentOffset)154 void SetCurrentOffset(float currentOffset) 155 { 156 currentOffset_ = currentOffset; 157 } 158 SetCurrentHeight(float currentHeight)159 void SetCurrentHeight(float currentHeight) 160 { 161 if (height_ != currentHeight) { 162 height_ = currentHeight; 163 ChangeScrollHeight(height_); 164 } 165 ProcessColumnRect(height_); 166 } 167 SetCurrentHeightToOverlay(float height)168 void SetCurrentHeightToOverlay(float height) 169 { 170 auto context = PipelineContext::GetCurrentContext(); 171 CHECK_NULL_VOID(context); 172 auto overlayManager = context->GetOverlayManager(); 173 CHECK_NULL_VOID(overlayManager); 174 overlayManager->SetSheetHeight(height); 175 } 176 177 void ChangeScrollHeight(float height); 178 GetFocusPattern()179 FocusPattern GetFocusPattern() const override 180 { 181 return { FocusType::SCOPE, true }; 182 } 183 IsExecuteOnDisappear()184 bool IsExecuteOnDisappear() const 185 { 186 return isExecuteOnDisappear_; 187 } 188 AvoidKeyboard()189 bool AvoidKeyboard() const override 190 { 191 return false; 192 } 193 194 void OnWindowSizeChanged(int32_t width, int32_t height, WindowSizeChangeReason type) override; 195 HasTitleNode()196 bool HasTitleNode() const 197 { 198 return titleId_.has_value(); 199 } 200 SetTitleId(const int32_t id)201 bool SetTitleId(const int32_t id) 202 { 203 if (HasTitleNode()) { 204 return false; 205 } 206 titleId_ = id; 207 return true; 208 } 209 GetTitleId()210 int32_t GetTitleId() 211 { 212 if (!titleId_.has_value()) { 213 titleId_ = ElementRegister::GetInstance()->MakeUniqueId(); 214 } 215 return titleId_.value(); 216 } 217 HasSubtitleNode()218 bool HasSubtitleNode() const 219 { 220 return titleId_.has_value(); 221 } 222 SetSubtitleId(const int32_t id)223 bool SetSubtitleId(const int32_t id) 224 { 225 if (HasSubtitleNode()) { 226 return false; 227 } 228 subtitleId_ = id; 229 return true; 230 } 231 GetSubtitleId()232 int32_t GetSubtitleId() 233 { 234 if (!subtitleId_.has_value()) { 235 subtitleId_ = ElementRegister::GetInstance()->MakeUniqueId(); 236 } 237 return subtitleId_.value(); 238 } 239 CalculateFriction(float gamma)240 static float CalculateFriction(float gamma) 241 { 242 constexpr float RATIO = 1.848f; 243 if (GreatOrEqual(gamma, 1.0)) { 244 gamma = 1.0f; 245 } 246 return exp(-RATIO * gamma); 247 } 248 249 SheetType GetSheetType(); 250 251 void BubbleStyleSheetTransition(bool isTransitionIn); 252 253 void StartOffsetEnteringAnimation(); 254 255 void StartAlphaEnteringAnimation(std::function<void()> finish); 256 257 void StartOffsetExitingAnimation(); 258 259 void StartAlphaExitingAnimation(std::function<void()> finish); 260 261 void ResetToInvisible(); 262 263 bool IsFold(); 264 GetAnimationBreak()265 bool GetAnimationBreak() const 266 { 267 return isAnimationBreak_; 268 } 269 SetAnimationProcess(bool isProcess)270 void SetAnimationProcess(bool isProcess) 271 { 272 isAnimationProcess_ = isProcess; 273 } 274 GetSheetMaxHeight()275 float GetSheetMaxHeight() 276 { 277 return pageHeight_; 278 } 279 GetSheetMaxWidth()280 float GetSheetMaxWidth() 281 { 282 return sheetMaxWidth_; 283 } 284 GetSheetOffset()285 float GetSheetOffset() 286 { 287 return sheetOffsetY_; 288 } 289 290 float GetFitContentHeight(); 291 292 void ProcessColumnRect(float height = 0.0f); 293 SetShowState(bool show)294 void SetShowState(bool show) 295 { 296 show_ = show; 297 } 298 GetShowState()299 bool GetShowState() const 300 { 301 return show_; 302 } 303 304 protected: 305 void OnDetachFromFrameNode(FrameNode* frameNode) override; 306 307 private: 308 void OnModifyDone() override; 309 void OnAttachToFrameNode() override; 310 void OnColorConfigurationUpdate() override; 311 bool OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& dirty, const DirtySwapConfig& config) override; 312 313 void InitPageHeight(); 314 void TranslateTo(float height); 315 void SetColumnMinSize(bool reset = false); 316 void UpdateDragBarStatus(); 317 void UpdateCloseIconStatus(); 318 void UpdateSheetTitle(); 319 void UpdateInteractive(); 320 RefPtr<RenderContext> GetRenderContext(); 321 bool PostTask(const TaskExecutor::Task& task); 322 void CheckSheetHeightChange(); 323 void InitSheetDetents(); 324 void HandleFitContontChange(float height); 325 void ChangeSheetHeight(float height); 326 void StartSheetTransitionAnimation(const AnimationOption& option, bool isTransitionIn, float offset); 327 void ClipSheetNode(); 328 std::string GetPopupStyleSheetClipPath(SizeF sheetSize, Dimension sheetRadius); 329 std::string GetCenterStyleSheetClipPath(SizeF sheetSize, Dimension sheetRadius); 330 std::string GetBottomStyleSheetClipPath(SizeF sheetSize, Dimension sheetRadius); 331 std::string MoveTo(double x, double y); 332 std::string LineTo(double x, double y); 333 std::string ArcTo(double rx, double ry, double rotation, int32_t arc_flag, double x, double y); 334 void DismissTransition(bool isTransitionIn, float dragVelocity = 0.0f); 335 uint32_t keyboardHeight_ = 0; 336 int32_t targetId_ = -1; 337 std::optional<int32_t> titleId_; 338 std::optional<int32_t> subtitleId_; 339 std::string targetTag_; 340 std::function<void(const std::string&)> callback_; 341 std::function<void()> onDisappear_; 342 std::function<void()> shouldDismiss_; 343 RefPtr<PanEvent> panEvent_; 344 float currentOffset_ = 0.0f; 345 346 float height_ = 0.0f; // sheet height, start from the bottom 347 float sheetHeight_ = 0.0f; 348 float pageHeight_ = 0.0f; 349 float scrollHeight_ = 0.0f; 350 float statusBarHeight_ = .0f; 351 bool isExecuteOnDisappear_ = false; 352 bool windowRotate_ = false; 353 bool firstMeasure_ = true; 354 bool isScrolling_ = false; 355 356 float sheetMaxHeight_ = 0.0f; 357 float sheetMaxWidth_ = 0.0f; 358 float centerHeight_ = 0.0f; 359 float sheetFitContentHeight_ = 0.0f; 360 float sheetOffsetX_ = 0.0f; 361 float sheetOffsetY_ = 0.0f; 362 bool isFirstInit_ = true; 363 bool isAnimationBreak_ = false; 364 bool isAnimationProcess_ = false; 365 SheetType sheetType_ = SheetType::SHEET_BOTTOM; 366 bool windowChanged_ = false; 367 368 std::string sheetThemeType_ = "auto"; 369 370 std::vector<float> sheetDetentHeight_; 371 372 std::shared_ptr<AnimationUtils::Animation> animation_; 373 374 bool show_ = true; 375 376 ACE_DISALLOW_COPY_AND_MOVE(SheetPresentationPattern); 377 }; 378 } // namespace OHOS::Ace::NG 379 380 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_OVERLAY_SHEET_PRESENTATION_PATTERN_H 381