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