1 /*
2  * Copyright (c) 2021-2022 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 #include "core/components/panel/render_sliding_panel.h"
17 
18 #include "base/log/dump_log.h"
19 #include "base/log/event_report.h"
20 #include "core/animation/spring_animation.h"
21 #include "core/components/common/layout/grid_system_manager.h"
22 #include "core/components/panel/sliding_events.h"
23 
24 namespace OHOS::Ace {
25 namespace {
26 
27 constexpr int32_t ANIMATION_BASE_DURATION = 256;
28 constexpr uint32_t FIND_MAX_COUNT = 64;
29 constexpr Dimension BLANK_MIN_HEIGHT = 8.0_vp;
30 constexpr Dimension DRAG_BAR_HEIGHT = 8.0_vp;
31 constexpr Dimension DRAG_UP_THRESHOLD = 48.0_vp;
32 constexpr double CONTENT_MIN_TOLERANCE = 0.01;
33 constexpr double VELOCITY_THRESHOLD = 1000.0; // Move 1000px per second.
34 
GetAnimationDuration(double delta,double dragRange)35 int32_t GetAnimationDuration(double delta, double dragRange)
36 {
37     if (NearZero(dragRange)) {
38         return 0;
39     }
40     return static_cast<int32_t>(((std::abs(delta) / dragRange) + 1.0) * ANIMATION_BASE_DURATION);
41 }
42 
43 template<class T>
FindChildOfClass(const RefPtr<RenderNode> & parent)44 RefPtr<T> FindChildOfClass(const RefPtr<RenderNode>& parent)
45 {
46     // BFS to find child in tree.
47     uint32_t findCount = 0;
48     auto searchQueue = parent->GetChildren(); // copy children to a queue
49     while (++findCount <= FIND_MAX_COUNT && !searchQueue.empty()) {
50         const auto child = searchQueue.front();
51         searchQueue.pop_front();
52         if (!child) {
53             continue;
54         }
55         if (AceType::InstanceOf<T>(child)) {
56             return AceType::DynamicCast<T>(child);
57         }
58         searchQueue.insert(searchQueue.end(), child->GetChildren().begin(), child->GetChildren().end());
59     }
60     return RefPtr<T>();
61 }
62 
63 } // namespace
64 
Create()65 RefPtr<RenderNode> RenderSlidingPanel::Create()
66 {
67     return AceType::MakeRefPtr<RenderSlidingPanel>();
68 }
69 
Update(const RefPtr<Component> & component)70 void RenderSlidingPanel::Update(const RefPtr<Component>& component)
71 {
72     auto slidingPanel = AceType::DynamicCast<SlidingPanelComponent>(component);
73     if (!slidingPanel) {
74         LOGE("slidingPanel update with nullptr");
75         EventReport::SendRenderException(RenderExcepType::RENDER_COMPONENT_ERR);
76         return;
77     }
78     InitializeRecognizer();
79     if (isFirstUpdate_) {
80         isFirstUpdate_ = false;
81         boxForBlank_ = RenderBox::Create();
82         AddChild(boxForBlank_, 0);
83         boxForBlank_->Attach(GetContext());
84         animator_ = CREATE_ANIMATOR(GetContext());
85     }
86     hasBoxStyle_ = slidingPanel->HasBoxStyle();
87     previousMode_ = mode_;
88     if ((slidingPanel->GetMode() != PanelMode::AUTO && previousMode_ != slidingPanel->GetMode()) ||
89         type_ != slidingPanel->GetType()) {
90         isFirstLayout_ = true;
91     }
92     mode_ = slidingPanel->GetMode() == PanelMode::AUTO ? PanelMode::FULL : slidingPanel->GetMode();
93     type_ = slidingPanel->GetType();
94     fullHeight_ = slidingPanel->GetFullHeight();
95     halfHeight_ = slidingPanel->GetHalfHeight();
96     miniHeight_ = slidingPanel->GetMiniHeight();
97     panelId_ = slidingPanel->GetPanelId();
98     visible = slidingPanel->Visible();
99     onSizeChange_ =
100         AceAsyncEvent<void(const std::shared_ptr<BaseEventInfo>&)>::Create(slidingPanel->GetOnSizeChanged(), context_);
101     onHeightChange_ = slidingPanel->GetOnHeightChanged();
102     MarkNeedLayout();
103 }
104 
OnPaintFinish()105 void RenderSlidingPanel::OnPaintFinish()
106 {
107 #if defined(PREVIEW)
108     auto context = context_.Upgrade();
109     if (!context) {
110         return;
111     }
112 
113     auto manager = context->GetAccessibilityManager();
114     if (manager) {
115         auto node = manager->GetAccessibilityNodeById(panelId_);
116         if (!node) {
117             LOGE("node is null");
118             return;
119         }
120 
121         auto viewScale = context->GetViewScale();
122         Size size = GetLayoutSize() * viewScale;
123         Offset globalOffset = GetGlobalOffset() * viewScale;
124         double height = blankHeight_ * viewScale;
125 
126         // blankHeight_ is the height from screen top to panel top
127         node->SetWidth(size.Width());
128         node->SetHeight(size.Height() - height);
129         node->SetLeft(globalOffset.GetX());
130         node->SetTop(height);
131         node->SetVisible(true);
132     }
133 #endif
134 }
135 
PerformLayout()136 void RenderSlidingPanel::PerformLayout()
137 {
138     if (!InitializeLayoutProps()) {
139         return;
140     }
141     auto maxSize = GetLayoutParam().GetMaxSize();
142     // SlidingPanelComponent's size is as large as the root's.
143     if (maxSize.IsInfinite()) {
144         SetLayoutSize(viewPort_);
145     } else {
146         SetLayoutSize(maxSize);
147     }
148     if (isFirstLayout_) {
149         blankHeight_ = GetLayoutParam().GetMaxSize().Height();
150         AnimateTo(defaultBlankHeights_[mode_], mode_);
151         if (previousMode_ != mode_) {
152             FireSizeChangeEvent();
153         }
154     } else {
155         InnerLayout();
156     }
157     isFirstLayout_ = false;
158     previousSize_ = maxSize;
159 }
160 
InitializeLayoutProps()161 bool RenderSlidingPanel::InitializeLayoutProps()
162 {
163     // Only 2 children are allowed in RenderSlidingPanel
164     if (GetChildren().empty() || GetChildren().size() != 2) {
165         LOGE("Children size wrong in slide panel modal");
166         return false;
167     }
168     if (!dragBar_) {
169         dragBar_ = FindChildOfClass<RenderDragBar>(GetChildren().back());
170         if (!dragBar_) {
171             LOGE("No drag bar in sliding panel. Cause error");
172             return false;
173         }
174     }
175     auto maxSize = GetLayoutParam().GetMaxSize();
176     if (defaultBlankHeights_.empty() || previousSize_ != maxSize) {
177         defaultBlankHeights_[PanelMode::MINI] = miniHeight_.second
178                                                     ? maxSize.Height() - NormalizeToPx(miniHeight_.first)
179                                                     : maxSize.Height() - NormalizeToPx(DRAG_UP_THRESHOLD);
180         defaultBlankHeights_[PanelMode::HALF] =
181             halfHeight_.second ? maxSize.Height() - NormalizeToPx(halfHeight_.first)
182             : maxSize.Height() / 2; // 2: half of height
183         defaultBlankHeights_[PanelMode::FULL] =
184             fullHeight_.second ? maxSize.Height() - NormalizeToPx(fullHeight_.first) : NormalizeToPx(BLANK_MIN_HEIGHT);
185         CheckHeightValidity();
186         isFirstLayout_ = true;
187         fullHalfBoundary_ = defaultBlankHeights_[PanelMode::FULL] +
188                             (defaultBlankHeights_[PanelMode::HALF] -
189                             defaultBlankHeights_[PanelMode::FULL]) / 2.0; // 2.0: half of height
190         halfMiniBoundary_ = defaultBlankHeights_[PanelMode::HALF] +
191                             (defaultBlankHeights_[PanelMode::MINI] -
192                             defaultBlankHeights_[PanelMode::HALF]) / 2.0; // 2.0: half of height
193         fullMiniBoundary_ = defaultBlankHeights_[PanelMode::FULL] +
194                             (defaultBlankHeights_[PanelMode::MINI] -
195                             defaultBlankHeights_[PanelMode::FULL]) / 2.0; // 2.0: half of height
196     }
197     minBlankHeight_ = NormalizeToPx(BLANK_MIN_HEIGHT);
198     if (dragBar_ && !(dragBar_->HasClickArrowCallback())) {
199         SetDragBarCallBack();
200     }
201     return true;
202 }
203 
CheckHeightValidity()204 void RenderSlidingPanel::CheckHeightValidity()
205 {
206     auto minBlank = NormalizeToPx(BLANK_MIN_HEIGHT);
207     auto maxBlank = GetLayoutParam().GetMaxSize().Height() - NormalizeToPx(DRAG_BAR_HEIGHT);
208     defaultBlankHeights_[PanelMode::MINI] = std::clamp(defaultBlankHeights_[PanelMode::MINI], minBlank, maxBlank);
209     defaultBlankHeights_[PanelMode::HALF] = std::clamp(defaultBlankHeights_[PanelMode::HALF], minBlank, maxBlank);
210     defaultBlankHeights_[PanelMode::FULL] = std::clamp(defaultBlankHeights_[PanelMode::FULL], minBlank, maxBlank);
211 }
212 
SetDragBarCallBack()213 void RenderSlidingPanel::SetDragBarCallBack()
214 {
215     dragBar_->SetClickArrowCallback([weak = WeakClaim(this)]() {
216         auto panel = weak.Upgrade();
217         if (!panel) {
218             LOGE("panel is nullptr");
219             return;
220         }
221         auto dragBar = panel->GetDragBar();
222         if (!dragBar) {
223             LOGE("dragBar is nullptr");
224             return;
225         }
226         panel->previousMode_ = panel->mode_;
227         if (panel->mode_ == PanelMode::MINI) {
228             panel->mode_ = panel->type_ == PanelType::MINI_BAR ? PanelMode::FULL : PanelMode::HALF;
229         } else if (panel->mode_ == PanelMode::FULL) {
230             panel->mode_ = panel->type_ == PanelType::MINI_BAR ? PanelMode::MINI : PanelMode::HALF;
231         }
232         panel->AnimateTo(panel->defaultBlankHeights_[panel->mode_], panel->mode_);
233         if (panel->previousMode_ != panel->mode_) {
234             panel->FireSizeChangeEvent();
235         }
236     });
237 }
238 
FireHeightChangeEvent()239 void RenderSlidingPanel::FireHeightChangeEvent()
240 {
241     if (!onHeightChange_) {
242         return;
243     }
244     int32_t currentHeight = static_cast<int32_t>(GetLayoutParam().GetMaxSize().Height() - blankHeight_);
245     if (!visible) {
246         currentHeight = 0;
247     }
248     onHeightChange_(currentHeight);
249 }
250 
FireSizeChangeEvent()251 void RenderSlidingPanel::FireSizeChangeEvent()
252 {
253     if (!onSizeChange_) {
254         return;
255     }
256     double height =
257         std::floor(GetLayoutSize().Height() - defaultBlankHeights_[mode_] - dragBar_->GetLayoutSize().Height());
258     double width = std::floor(GetLayoutSize().Width());
259     onSizeChange_(std::make_shared<SlidingPanelSizeChangeEvent>(mode_, width, height));
260 }
261 
InnerLayout()262 void RenderSlidingPanel::InnerLayout()
263 {
264     LayoutParam innerLayout;
265     auto maxSize = GetLayoutParam().GetMaxSize();
266     auto columnInfo = GridSystemManager::GetInstance().GetInfoByType(GridColumnType::PANEL);
267     columnInfo->GetParent()->BuildColumnWidth();
268     auto maxWidth = columnInfo->GetWidth() + 2 * NormalizeToPx(columnInfo->GetParent()->GetGutterWidth());
269     if (GridSystemManager::GetInstance().GetCurrentSize() <= GridSizeType::SM) {
270         maxWidth = maxSize.Width();
271     }
272     innerLayout.SetFixedSize(Size(maxWidth, blankHeight_));
273     boxForBlank_->Layout(innerLayout);
274     boxForBlank_->SetPosition(Offset::Zero());
275     auto contentHeight = maxSize.Height() - blankHeight_;
276     innerLayout.SetMinSize(Size());
277     innerLayout.SetMaxSize(Size(maxWidth, contentHeight));
278     auto boxForContent = GetChildren().back();
279     boxForContent->Layout(innerLayout);
280     auto centerX = (maxSize.Width() - maxWidth) / 2;
281     boxForContent->SetPosition(Offset(centerX, blankHeight_));
282     double viewPortHeight = maxSize.Height() - blankHeight_ - dragBar_->GetLayoutSize().Height();
283     viewPort_ = Size(maxWidth, viewPortHeight);
284 }
285 
ResetContentHeight()286 void RenderSlidingPanel::ResetContentHeight()
287 {
288     AnimateTo(dragStartBlankHeight_, mode_);
289 }
290 
OnAnimationStop()291 void RenderSlidingPanel::OnAnimationStop()
292 {
293     isAnimating_ = false;
294 }
295 
InitializeRecognizer()296 void RenderSlidingPanel::InitializeRecognizer()
297 {
298     if (!dragDetector_) {
299         dragDetector_ = AceType::MakeRefPtr<VerticalDragRecognizer>();
300         dragDetector_->SetOnDragStart([weak = WeakClaim(this)](const DragStartInfo& startInfo) {
301             auto panel = weak.Upgrade();
302             if (panel) {
303                 panel->HandleDragStart(startInfo.GetLocalLocation());
304             }
305         });
306         dragDetector_->SetOnDragUpdate([weakDrag = AceType::WeakClaim(this)](const DragUpdateInfo& info) {
307             auto panel = weakDrag.Upgrade();
308             if (panel) {
309                 panel->HandleDragUpdate(info.GetLocalLocation());
310             }
311         });
312         dragDetector_->SetOnDragEnd([weakDrag = AceType::WeakClaim(this)](const DragEndInfo& info) {
313             auto panel = weakDrag.Upgrade();
314             if (panel) {
315                 panel->HandleDragEnd(info.GetLocalLocation(), info.GetMainVelocity());
316             }
317         });
318         dragDetector_->SetOnDragCancel([weakDrag = AceType::WeakClaim(this)]() {
319             auto panel = weakDrag.Upgrade();
320             if (panel) {
321                 panel->HandleDragEnd({}, 0.0);
322             }
323         });
324     }
325 }
326 
TouchTest(const Point & globalPoint,const Point & parentLocalPoint,const TouchRestrict & touchRestrict,TouchTestResult & result)327 bool RenderSlidingPanel::TouchTest(const Point& globalPoint, const Point& parentLocalPoint,
328     const TouchRestrict& touchRestrict, TouchTestResult& result)
329 {
330     // Forbidden vertical swipe of all children in not full mode.
331     TouchRestrict newRestrict = touchRestrict;
332     if (mode_ != PanelMode::FULL) {
333         newRestrict.UpdateForbiddenType(TouchRestrict::SWIPE_VERTICAL);
334     }
335     if (!GetChildren().empty()) {
336         touchRect_ = GetChildren().back()->GetPaintRect();
337     }
338     return RenderNode::TouchTest(globalPoint, parentLocalPoint, newRestrict, result);
339 }
340 
OnTouchTestHit(const Offset & coordinateOffset,const TouchRestrict & touchRestrict,TouchTestResult & result)341 void RenderSlidingPanel::OnTouchTestHit(
342     const Offset& coordinateOffset, const TouchRestrict& touchRestrict, TouchTestResult& result)
343 {
344     if (isAnimating_) {
345         return;
346     }
347     if (dragDetector_) {
348         dragDetector_->SetCoordinateOffset(coordinateOffset);
349         result.emplace_back(dragDetector_);
350     }
351 }
352 
UpdateTouchRect()353 void RenderSlidingPanel::UpdateTouchRect()
354 {
355     touchRect_ = GetPaintRect();
356     touchRectList_.emplace_back(touchRect_);
357     SetTouchRectList(touchRectList_);
358     if (GetChildren().size() < 2) { // 2: at least 2 children
359         return;
360     }
361     touchRect_ = GetChildren().back()->GetPaintRect();
362     touchRectList_.emplace_back(touchRect_);
363     SetTouchRectList(touchRectList_);
364 }
365 
LiftPanelForVirtualKeyboard(double offsetY)366 void RenderSlidingPanel::LiftPanelForVirtualKeyboard(double offsetY)
367 {
368     double maxBlankHeight = GetLayoutSize().Height() - CONTENT_MIN_TOLERANCE;
369     if (dragBar_) {
370         maxBlankHeight -= dragBar_->GetLayoutSize().Height();
371     }
372     blankHeight_ = std::min(blankHeight_ + offsetY, maxBlankHeight);
373     FireHeightChangeEvent();
374     MarkNeedLayout();
375 }
376 
UpdatePanelHeightByCurrentMode()377 void RenderSlidingPanel::UpdatePanelHeightByCurrentMode()
378 {
379     AnimateTo(defaultBlankHeights_[mode_], mode_);
380 }
381 
HandleDragStart(const Offset & startPoint)382 void RenderSlidingPanel::HandleDragStart(const Offset& startPoint)
383 {
384     if (isAnimating_) {
385         return;
386     }
387     dragStartPoint_ = startPoint;
388     dragStartBlankHeight_ = blankHeight_;
389 }
390 
HandleDragUpdate(const Offset & currentPoint)391 void RenderSlidingPanel::HandleDragUpdate(const Offset& currentPoint)
392 {
393     if (isAnimating_) {
394         return;
395     }
396     double targetBlankHeight = dragStartBlankHeight_ + currentPoint.GetY() - dragStartPoint_.GetY();
397     if (targetBlankHeight < minBlankHeight_) {
398         targetBlankHeight = minBlankHeight_;
399     }
400     // Do not drag to make page content height <= zero.
401     double maxBlankHeight = GetLayoutSize().Height() - CONTENT_MIN_TOLERANCE;
402     if (dragBar_) {
403         maxBlankHeight -= dragBar_->GetLayoutSize().Height();
404     }
405     if (targetBlankHeight > maxBlankHeight) {
406         targetBlankHeight = maxBlankHeight;
407     }
408     blankHeight_ = targetBlankHeight;
409     FireHeightChangeEvent();
410     MarkNeedLayout();
411 }
412 
HandleDragEnd(const Offset & endPoint,double velocity)413 void RenderSlidingPanel::HandleDragEnd(const Offset& endPoint, double velocity)
414 {
415     if (isAnimating_) {
416         return;
417     }
418     previousMode_ = mode_;
419     auto dragStart = dragStartPoint_.GetY();
420     auto dragLen = endPoint.GetY() - dragStart;
421     switch (type_) {
422         case PanelType::MINI_BAR: { // FULL & MINI
423             CalculateModeTypeMini(dragLen, velocity);
424             break;
425         }
426         case PanelType::FOLDABLE_BAR: { // FULL & HALF & MINI
427             CalculateModeTypeFold(dragLen, velocity);
428             break;
429         }
430         case PanelType::TEMP_DISPLAY: { // FULL & HALF
431             CalculateModeTypeTemp(dragLen, velocity);
432             break;
433         }
434         default: {
435             LOGE("Unsupported type:%{public}d", type_);
436             return;
437         }
438     }
439     AnimateTo(defaultBlankHeights_[mode_], mode_);
440     if (previousMode_ != mode_) {
441         FireSizeChangeEvent();
442     }
443 }
444 
CalculateModeTypeMini(double dragLen,double velocity)445 void RenderSlidingPanel::CalculateModeTypeMini(double dragLen, double velocity) // FULL & MINI
446 {
447     double currentPostion = defaultBlankHeights_[mode_] + dragLen;
448     if (std::abs(velocity) < VELOCITY_THRESHOLD) {
449         // Drag velocity not reached to threshold, mode based on the location.
450         if (currentPostion < fullMiniBoundary_) {
451             mode_ = PanelMode::FULL;
452         } else {
453             mode_ = PanelMode::MINI;
454         }
455     } else {
456         // Drag velocity reached to threshold, mode based on the drag direction.
457         if (velocity > 0.0) {
458             mode_ = PanelMode::MINI;
459         } else {
460             mode_ = PanelMode::FULL;
461         }
462     }
463 }
464 
CalculateModeTypeFold(double dragLen,double velocity)465 void RenderSlidingPanel::CalculateModeTypeFold(double dragLen, double velocity) // FULL & HALF & MINI
466 {
467     double currentPostion = defaultBlankHeights_[mode_] + dragLen;
468     if (std::abs(velocity) < VELOCITY_THRESHOLD) {
469         // Drag velocity not reached to threshold, mode based on the location.
470         if (currentPostion < fullHalfBoundary_) {
471             mode_ = PanelMode::FULL;
472         } else if (currentPostion < halfMiniBoundary_) {
473             mode_ = PanelMode::HALF;
474         } else {
475             mode_ = PanelMode::MINI;
476         }
477     } else {
478         // Drag velocity reached to threshold, mode based on the drag direction.
479         if (velocity > 0.0) {
480             if (currentPostion < defaultBlankHeights_[PanelMode::HALF]) {
481                 mode_ = PanelMode::HALF;
482             } else {
483                 mode_ = PanelMode::MINI;
484             }
485         } else {
486             if (currentPostion > defaultBlankHeights_[PanelMode::HALF]) {
487                 mode_ = PanelMode::HALF;
488             } else {
489                 mode_ = PanelMode::FULL;
490             }
491         }
492     }
493 }
494 
CalculateModeTypeTemp(double dragLen,double velocity)495 void RenderSlidingPanel::CalculateModeTypeTemp(double dragLen, double velocity) // FULL & HALF
496 {
497     double currentPostion = defaultBlankHeights_[mode_] + dragLen;
498     if (std::abs(velocity) < VELOCITY_THRESHOLD) {
499         // Drag velocity not reached to threshold, mode based on the location.
500         if (currentPostion < fullHalfBoundary_) {
501             mode_ = PanelMode::FULL;
502         } else {
503             mode_ = PanelMode::HALF;
504         }
505     } else {
506         // Drag velocity reached to threshold, mode based on the drag direction.
507         if (velocity > 0.0) {
508             mode_ = PanelMode::HALF;
509         } else {
510             mode_ = PanelMode::FULL;
511         }
512     }
513 }
514 
AppendBlankHeightAnimation(double blankHeight,PanelMode mode)515 void RenderSlidingPanel::AppendBlankHeightAnimation(double blankHeight, PanelMode mode)
516 {
517     if (LessNotEqual(blankHeight_, 0.0) || NearEqual(blankHeight_, blankHeight)) {
518         LOGE("Append animation failed. Blank height less than zero.");
519         return;
520     }
521 
522     // Mass: 1.0, stiffness: 100.0f, damping: 20.0f. For Critical Damped.
523     auto springProperty = AceType::MakeRefPtr<SpringProperty>(1.0f, 100.0f, 20.0f);
524     auto heightAnimation = AceType::MakeRefPtr<SpringAnimation>(springProperty);
525     heightAnimation->AddListener(
526         [weak = AceType::WeakClaim(this), start = blankHeight_, end = blankHeight, mode](const double& value) {
527             auto panel = weak.Upgrade();
528             if (!panel) {
529                 LOGE("Panel is null.");
530                 return;
531             }
532             if (value > 1.0) {
533                 panel->dragBar_->ShowInPanelMode(mode);
534             }
535             panel->blankHeight_ = start + (end - start) * value;
536             panel->FireHeightChangeEvent();
537             panel->MarkNeedLayout();
538         });
539     animator_->AddInterpolator(heightAnimation);
540 }
541 
AnimateTo(double blankHeight,PanelMode mode)542 void RenderSlidingPanel::AnimateTo(double blankHeight, PanelMode mode)
543 {
544     isAnimating_ = true;
545     animator_->ClearInterpolators();
546     animator_->ClearAllListeners();
547     if (animator_->IsRunning()) {
548         animator_->Stop();
549     }
550     animator_->AddStopListener([weak = WeakClaim(this), mode]() {
551         auto panel = weak.Upgrade();
552         if (panel && panel->dragBar_) {
553             panel->OnAnimationStop();
554             panel->dragBar_->ShowInPanelMode(mode);
555         }
556     });
557     AppendBlankHeightAnimation(blankHeight, mode);
558     auto dragRange = GetLayoutParam().GetMaxSize().Height();
559     animator_->SetDuration(GetAnimationDuration(blankHeight - blankHeight_, dragRange));
560     animator_->SetFillMode(FillMode::FORWARDS);
561     animator_->Forward();
562 }
563 
Dump()564 void RenderSlidingPanel::Dump()
565 {
566     DumpLog::GetInstance().AddDesc(std::string("PanelMode:").append(std::to_string(static_cast<int32_t>(mode_))));
567     DumpLog::GetInstance().AddDesc(std::string("blankHeight: ").append(std::to_string(blankHeight_)));
568 }
569 
570 } // namespace OHOS::Ace
571