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