1 /*
2  * Copyright (c) 2022-2024 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_ng/pattern/panel/sliding_panel_pattern.h"
17 
18 #include <algorithm>
19 #include <cmath>
20 #include <cstddef>
21 #include <cstdint>
22 
23 #include "base/geometry/axis.h"
24 #include "base/geometry/dimension.h"
25 #include "base/log/log.h"
26 #include "base/memory/ace_type.h"
27 #include "base/utils/utils.h"
28 #include "core/animation/friction_motion.h"
29 #include "core/animation/spring_animation.h"
30 #include "core/components/close_icon/close_icon_theme.h"
31 #include "core/components_ng/base/frame_node.h"
32 #include "core/components_ng/base/inspector_filter.h"
33 #include "core/components_ng/layout/layout_wrapper.h"
34 #include "core/components_ng/pattern/panel/sliding_panel_layout_property.h"
35 #include "core/components_ng/property/measure_property.h"
36 #include "core/components_ng/property/property.h"
37 #include "core/event/touch_event.h"
38 #include "core/pipeline_ng/pipeline_context.h"
39 
40 namespace OHOS::Ace::NG {
41 namespace {
42 
43 constexpr int32_t ANIMATION_BASE_DURATION = 256;
44 constexpr Dimension BLANK_MIN_HEIGHT = 8.0_vp;
45 constexpr Dimension DRAG_UP_THRESHOLD = 48.0_vp;
46 constexpr double VELOCITY_THRESHOLD = 1000.0; // Move 1000px per second.
47 constexpr int32_t FRAME_RATE = 120;
48 
49 } // namespace
50 
OnModifyDone()51 void SlidingPanelPattern::OnModifyDone()
52 {
53     Pattern::OnModifyDone();
54     auto host = GetHost();
55     CHECK_NULL_VOID(host);
56     auto layoutProperty = host->GetLayoutProperty<SlidingPanelLayoutProperty>();
57     CHECK_NULL_VOID(layoutProperty);
58     auto hub = host->GetEventHub<EventHub>();
59     CHECK_NULL_VOID(hub);
60     auto gestureHub = hub->GetOrCreateGestureEventHub();
61     CHECK_NULL_VOID(gestureHub);
62     InitPanEvent(gestureHub);
63     if (layoutProperty->GetPanelType() == PanelType::CUSTOM) {
64         auto calc = layoutProperty->GetCustomHeight().value_or(Dimension(0.0));
65         if (!calc.CalcValue().empty() && calc.CalcValue().find("wrapContent") != std::string::npos) {
66             ResetLayoutWeight();
67         }
68     }
69     Update();
70     AddOrRemoveDragBarNode(layoutProperty);
71     AddOrRemoveCloseIconNode(layoutProperty);
72     if (layoutProperty->GetHasDragBarValue(true)) {
73         auto dragBar = GetDragBarNode();
74         CHECK_NULL_VOID(dragBar);
75         auto dragBarPattern = dragBar->GetPattern<DragBarPattern>();
76         CHECK_NULL_VOID(dragBarPattern);
77         if (dragBarPattern && !(dragBarPattern->HasClickArrowCallback())) {
78             SetDragBarCallBack();
79         }
80     }
81 
82     if (layoutProperty->GetShowCloseIconValue(false)) {
83         auto closeIconNode = GetCloseIconNode();
84         CHECK_NULL_VOID(closeIconNode);
85         auto closeIconPattern = closeIconNode->GetPattern<CloseIconPattern>();
86         CHECK_NULL_VOID(closeIconPattern);
87         if (closeIconPattern && !(closeIconPattern->HasClickButtonCallback())) {
88             SetCloseIconCallBack();
89         }
90     }
91     UpdatePanelRenderContext();
92 }
93 
UpdatePanelRenderContext()94 void SlidingPanelPattern::UpdatePanelRenderContext()
95 {
96     auto host = GetHost();
97     CHECK_NULL_VOID(host);
98     auto layoutProperty = host->GetLayoutProperty<SlidingPanelLayoutProperty>();
99     CHECK_NULL_VOID(layoutProperty);
100     auto renderContext = host->GetRenderContext();
101     CHECK_NULL_VOID(renderContext);
102     if (renderContext->HasBorderRadius()) {
103         auto child = host->GetChildAtIndex(0);
104         CHECK_NULL_VOID(child);
105         auto node = AceType::DynamicCast<FrameNode>(child);
106         CHECK_NULL_VOID(node);
107         auto panelRenderContext = node->GetRenderContext();
108         CHECK_NULL_VOID(panelRenderContext);
109         panelRenderContext->UpdateBorderRadius(renderContext->GetBorderRadius().value());
110     }
111     auto isShow = layoutProperty->GetIsShowValue(false);
112     auto backgroundMask = layoutProperty->GetBackgroundMaskValue(Color::TRANSPARENT);
113     renderContext->UpdateBackgroundColor(isShow ? backgroundMask : Color::TRANSPARENT);
114     if (isShow_.has_value() && isShow != isShow_.value_or(false)) {
115         if (preAnimateFlag_ && !isShowQueue_.empty()) {
116             isShowQueue_.pop();
117         }
118 
119         preAnimateFlag_ = true;
120         isShowQueue_.push(isShow);
121         if (isShowQueue_.size() == 1 && isShowQueue_.front()) {
122             invisibleFlag_ = false;
123         }
124         return;
125     }
126     invisibleFlag_ = !isShow;
127 }
128 
OnAttachToFrameNode()129 void SlidingPanelPattern::OnAttachToFrameNode()
130 {
131     auto host = GetHost();
132     CHECK_NULL_VOID(host);
133     host->GetRenderContext()->SetClipToFrame(true);
134     auto pipelineContext = PipelineContext::GetCurrentContext();
135     CHECK_NULL_VOID(pipelineContext);
136     pipelineContext->AddWindowSizeChangeCallback(host->GetId());
137 }
138 
OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper> & dirty,const DirtySwapConfig & config)139 bool SlidingPanelPattern::OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& dirty, const DirtySwapConfig& config)
140 {
141     if (config.skipMeasure && config.skipLayout) {
142         return false;
143     }
144 
145     auto layoutProperty = AceType::DynamicCast<SlidingPanelLayoutProperty>(dirty->GetLayoutProperty());
146     CHECK_NULL_RETURN(layoutProperty, false);
147     auto layoutConstraint = layoutProperty->GetLayoutConstraint();
148     CHECK_NULL_RETURN(layoutConstraint, false);
149     if (layoutConstraint->maxSize.Width() == 0.0f && layoutConstraint->maxSize.Height() == 0.0f) {
150         return false;
151     }
152 
153     auto layoutAlgorithmWrapper = DynamicCast<LayoutAlgorithmWrapper>(dirty->GetLayoutAlgorithm());
154     CHECK_NULL_RETURN(layoutAlgorithmWrapper, false);
155     auto layoutAlgorithm = DynamicCast<SlidingPanelLayoutAlgorithm>(layoutAlgorithmWrapper->GetLayoutAlgorithm());
156     CHECK_NULL_RETURN(layoutAlgorithm, false);
157     customHeight_ = layoutAlgorithm->GetCustomHeight();
158     InitializeLayoutProps();
159     isFirstLayout_ = layoutAlgorithm->GetIsFirstLayout();
160     fullHeight_ = layoutAlgorithm->GetFullHeight();
161     halfHeight_ = layoutAlgorithm->GetHalfHeight();
162     miniHeight_ = layoutAlgorithm->GetMiniHeight();
163     maxWidth_ = layoutAlgorithm->GetMaxWidth();
164     return true;
165 }
166 
OnWindowSizeChanged(int32_t width,int32_t height,WindowSizeChangeReason type)167 void SlidingPanelPattern::OnWindowSizeChanged(int32_t width, int32_t height, WindowSizeChangeReason type)
168 {
169     if (type != WindowSizeChangeReason::ROTATION) {
170         return;
171     }
172 
173     auto host = GetHost();
174     CHECK_NULL_VOID(host);
175     host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
176     auto context = PipelineContext::GetCurrentContext();
177     CHECK_NULL_VOID(context);
178     context->AddAfterLayoutTask([weak = WeakClaim(this)]() {
179         auto pattern = weak.Upgrade();
180         CHECK_NULL_VOID(pattern);
181         pattern->FireHeightChangeEvent();
182     });
183 }
184 
Update()185 void SlidingPanelPattern::Update()
186 {
187     auto layoutProperty = GetLayoutProperty<SlidingPanelLayoutProperty>();
188     type_ = layoutProperty->GetPanelType().value_or(PanelType::FOLDABLE_BAR);
189     if (!mode_.has_value()) {
190         mode_ = layoutProperty->GetPanelMode() == PanelMode::AUTO
191                     ? PanelMode::FULL
192                     : layoutProperty->GetPanelMode().value_or(PanelMode::HALF);
193         if (type_ == PanelType::CUSTOM) {
194             mode_ = PanelMode::CUSTOM;
195         }
196         return;
197     }
198     auto mode = layoutProperty->GetPanelMode() == PanelMode::AUTO
199                     ? PanelMode::FULL
200                     : layoutProperty->GetPanelMode().value_or(PanelMode::HALF);
201     if (type_ == PanelType::CUSTOM) {
202         mode = PanelMode::CUSTOM;
203     }
204     if (mode_.value() == mode) {
205         if (mode == PanelMode::HALF && type_ == PanelType::MINI_BAR) {
206             mode = PanelMode::MINI;
207         }
208         if (mode == PanelMode::MINI && type_ == PanelType::TEMP_DISPLAY) {
209             mode = PanelMode::HALF;
210         }
211     }
212     auto isShow = layoutProperty->GetIsShowValue(true);
213     if (mode_.value() != mode) {
214         mode_ = mode;
215         CheckPanelModeAndType();
216         if (isShow_.has_value() && isShow_.value() == isShow) {
217             AnimateTo(defaultBlankHeights_[mode_.value_or(PanelMode::HALF)], mode_.value_or(PanelMode::HALF));
218             if (previousMode_ != mode_.value_or(PanelMode::HALF)) {
219                 FireSizeChangeEvent();
220             }
221         }
222     }
223 }
224 
InitializeLayoutProps()225 void SlidingPanelPattern::InitializeLayoutProps()
226 {
227     auto host = GetHost();
228     CHECK_NULL_VOID(host);
229     auto child = host->GetChildren();
230     if (child.empty() || child.size() > 2) {
231         TAG_LOGW(AceLogTag::ACE_PANEL, "Children size wrong in slide panel modal");
232         return;
233     }
234 
235     auto maxSize = host->GetGeometryNode()->GetFrameSize();
236     maxSize_ = maxSize;
237     auto layoutProperty = GetLayoutProperty<SlidingPanelLayoutProperty>();
238     auto defaultFullHeight = Dimension(maxSize.Height() - BLANK_MIN_HEIGHT.ConvertToPx());
239     auto fullHeight = layoutProperty->GetFullHeight().value_or(defaultFullHeight).ConvertToPx();
240     auto halfHeight = layoutProperty->GetHalfHeight().value_or(defaultFullHeight / 2).ConvertToPx();
241     auto miniHeight =
242         layoutProperty->GetMiniHeight().value_or(Dimension(DRAG_UP_THRESHOLD.ConvertToPx())).ConvertToPx();
243     defaultBlankHeights_[PanelMode::FULL] = maxSize.Height() - fullHeight;
244     defaultBlankHeights_[PanelMode::HALF] = maxSize.Height() - halfHeight;
245     defaultBlankHeights_[PanelMode::MINI] = maxSize.Height() - miniHeight;
246     defaultBlankHeights_[PanelMode::AUTO] = maxSize.Height();
247     defaultBlankHeights_[PanelMode::CUSTOM] = maxSize.Height() - customHeight_.ConvertToPx();
248     CheckHeightValidity();
249     fullHalfBoundary_ = defaultBlankHeights_[PanelMode::FULL] +
250                         (defaultBlankHeights_[PanelMode::HALF] - defaultBlankHeights_[PanelMode::FULL]) / 2.0;
251     halfMiniBoundary_ = defaultBlankHeights_[PanelMode::HALF] +
252                         (defaultBlankHeights_[PanelMode::MINI] - defaultBlankHeights_[PanelMode::HALF]) / 2.0;
253     fullMiniBoundary_ = defaultBlankHeights_[PanelMode::FULL] +
254                         (defaultBlankHeights_[PanelMode::MINI] - defaultBlankHeights_[PanelMode::FULL]) / 2.0;
255     minBlankHeight_ = BLANK_MIN_HEIGHT.ConvertToPx();
256 
257     if (!isShow_.has_value()) {
258         FirstLayout();
259         return;
260     }
261     auto isShow = layoutProperty->GetIsShowValue(false);
262     if (isShow_.value() != isShow) {
263         IsShowChanged(isShow);
264         return;
265     }
266     HeightDynamicUpdate();
267 }
268 
FirstLayout()269 void SlidingPanelPattern::FirstLayout()
270 {
271     auto host = GetHost();
272     CHECK_NULL_VOID(host);
273     isFirstLayout_ = false;
274     auto layoutProperty = GetLayoutProperty<SlidingPanelLayoutProperty>();
275     CHECK_NULL_VOID(layoutProperty);
276     auto maxSize = host->GetGeometryNode()->GetFrameSize();
277     if (layoutProperty->GetIsShowValue(false) == true) {
278         CheckPanelModeAndType();
279         currentOffset_ = maxSize.Height();
280         AnimateTo(defaultBlankHeights_[mode_.value_or(PanelMode::HALF)], mode_.value_or(PanelMode::HALF));
281         if (previousMode_ != mode_.value_or(PanelMode::HALF)) {
282             FireSizeChangeEvent();
283         }
284         isShow_ = true;
285         SetIsViewRootScopeFocused(false);
286         FocusViewShow();
287         if (layoutProperty->GetHasDragBarValue(true)) {
288             auto dragBar = GetDragBarNode();
289             CHECK_NULL_VOID(dragBar);
290             auto dragBarPattern = dragBar->GetPattern<DragBarPattern>();
291             CHECK_NULL_VOID(dragBarPattern);
292             dragBarPattern->ShowInPanelMode(mode_.value_or(PanelMode::HALF));
293         }
294         return;
295     }
296     auto rootHeight = PipelineContext::GetCurrentRootHeight();
297     CheckPanelModeAndType();
298     currentOffset_ = rootHeight;
299     isShow_ = false;
300 }
301 
IsShowChanged(bool isShow)302 void SlidingPanelPattern::IsShowChanged(bool isShow)
303 {
304     auto host = GetHost();
305     CHECK_NULL_VOID(host);
306     if (isShow) {
307         SetIsViewRootScopeFocused(false);
308         FocusViewShow();
309     } else {
310         FocusViewClose();
311     }
312     auto layoutProperty = GetLayoutProperty<SlidingPanelLayoutProperty>();
313     CHECK_NULL_VOID(layoutProperty);
314     auto hasDragBar = layoutProperty->GetHasDragBarValue(true);
315     if (isShow) {
316         isShow_ = true;
317         CheckPanelModeAndType();
318         AnimateTo(defaultBlankHeights_[mode_.value_or(PanelMode::HALF)], mode_.value_or(PanelMode::HALF));
319         if (previousMode_ != mode_.value_or(PanelMode::HALF)) {
320             FireSizeChangeEvent();
321         }
322         if (hasDragBar) {
323             auto dragBar = GetDragBarNode();
324             CHECK_NULL_VOID(dragBar);
325             auto dragBarPattern = dragBar->GetPattern<DragBarPattern>();
326             CHECK_NULL_VOID(dragBarPattern);
327             dragBarPattern->ShowInPanelMode(mode_.value_or(PanelMode::HALF));
328         }
329         return;
330     }
331     isShow_ = false;
332     auto rootHeight = PipelineContext::GetCurrentRootHeight();
333     AnimateTo(rootHeight, mode_.value_or(PanelMode::HALF));
334     if (hasDragBar) {
335         auto dragBar = GetDragBarNode();
336         CHECK_NULL_VOID(dragBar);
337         auto dragBarPattern = dragBar->GetPattern<DragBarPattern>();
338         CHECK_NULL_VOID(dragBarPattern);
339         dragBarPattern->ShowInPanelMode(mode_.value_or(PanelMode::HALF));
340     }
341 }
342 
HeightDynamicUpdate()343 void SlidingPanelPattern::HeightDynamicUpdate()
344 {
345     if (isShow_.value_or(false) == true && !isDrag_ && !isAnimating_) {
346         if (isClosePanel_) {
347             return;
348         }
349         switch (previousMode_) {
350             case PanelMode::FULL:
351                 if (!NearEqual(currentOffset_, defaultBlankHeights_[PanelMode::FULL])) {
352                     AnimateTo(defaultBlankHeights_[PanelMode::FULL], PanelMode::FULL);
353                 }
354                 break;
355             case PanelMode::HALF:
356                 if (!NearEqual(currentOffset_, defaultBlankHeights_[PanelMode::HALF])) {
357                     AnimateTo(defaultBlankHeights_[PanelMode::HALF], PanelMode::HALF);
358                 }
359                 break;
360             case PanelMode::MINI:
361                 if (!NearEqual(currentOffset_, defaultBlankHeights_[PanelMode::MINI])) {
362                     AnimateTo(defaultBlankHeights_[PanelMode::MINI], PanelMode::MINI);
363                 }
364                 break;
365             case PanelMode::CUSTOM:
366                 if (!NearEqual(currentOffset_, defaultBlankHeights_[PanelMode::CUSTOM])) {
367                     AnimateTo(defaultBlankHeights_[PanelMode::CUSTOM], PanelMode::CUSTOM);
368                 }
369                 break;
370             default:
371                 break;
372         }
373     }
374 }
375 
CheckHeightValidity()376 void SlidingPanelPattern::CheckHeightValidity()
377 {
378     auto minBlank = BLANK_MIN_HEIGHT.ConvertToPx();
379     auto host = GetHost();
380     CHECK_NULL_VOID(host);
381     auto geometryNode = host->GetGeometryNode();
382 
383     auto maxBlank = static_cast<double>(geometryNode->GetFrameSize().Height());
384     defaultBlankHeights_[PanelMode::MINI] = std::clamp(defaultBlankHeights_[PanelMode::MINI], minBlank, maxBlank);
385     defaultBlankHeights_[PanelMode::HALF] = std::clamp(defaultBlankHeights_[PanelMode::HALF], minBlank, maxBlank);
386     defaultBlankHeights_[PanelMode::FULL] = std::clamp(defaultBlankHeights_[PanelMode::FULL], minBlank, maxBlank);
387     defaultBlankHeights_[PanelMode::CUSTOM] = std::clamp(defaultBlankHeights_[PanelMode::CUSTOM], minBlank, maxBlank);
388 }
389 
CheckPanelModeAndType()390 void SlidingPanelPattern::CheckPanelModeAndType()
391 {
392     // This parameter does not take effect when PanelMode is set to Half and PanelType is set to minibar
393     if (mode_.value_or(PanelMode::HALF) == PanelMode::HALF && type_ == PanelType::MINI_BAR) {
394         mode_ = PanelMode::MINI;
395     }
396 
397     // This parameter does not take effect when PanelMode is set to Mini and PanelType is set to temporary
398     if (mode_.value_or(PanelMode::HALF) == PanelMode::MINI && type_ == PanelType::TEMP_DISPLAY) {
399         mode_ = PanelMode::HALF;
400     }
401 }
402 
InitPanEvent(const RefPtr<GestureEventHub> & gestureHub)403 void SlidingPanelPattern::InitPanEvent(const RefPtr<GestureEventHub>& gestureHub)
404 {
405     if (!IsNeedResetPanEvent(gestureHub)) {
406         return;
407     }
408     auto actionStartTask = [weak = WeakClaim(this)](const GestureEvent& startInfo) {
409         auto pattern = weak.Upgrade();
410         if (pattern) {
411             pattern->HandleDragStart(startInfo.GetLocalLocation());
412         }
413     };
414     auto actionUpdateTask = [weak = WeakClaim(this)](const GestureEvent& info) {
415         auto pattern = weak.Upgrade();
416         if (pattern) {
417             pattern->HandleDragUpdate(info);
418         }
419     };
420     auto actionEndTask = [weak = WeakClaim(this)](const GestureEvent& info) {
421         auto pattern = weak.Upgrade();
422         if (pattern) {
423             pattern->HandleDragEnd(info.GetMainVelocity());
424         }
425     };
426     auto actionCancelTask = [weak = WeakClaim(this)]() {
427         auto pattern = weak.Upgrade();
428         if (pattern) {
429             pattern->HandleDragEnd({});
430         }
431     };
432     PanDirection panDirection;
433     panDirection.type = PanDirection::VERTICAL;
434     auto layoutProperty = GetLayoutProperty<SlidingPanelLayoutProperty>();
435     auto type = layoutProperty->GetPanelType().value_or(PanelType::FOLDABLE_BAR);
436     panEvent_ = type == PanelType::CUSTOM ? MakeRefPtr<PanEvent>(nullptr, nullptr, nullptr,
437      std::move(actionCancelTask)) : MakeRefPtr<PanEvent>(std::move(actionStartTask),
438      std::move(actionUpdateTask), std::move(actionEndTask), std::move(actionCancelTask));
439     gestureHub->AddPanEvent(panEvent_, panDirection, 1, DEFAULT_PAN_DISTANCE);
440 }
441 
IsNeedResetPanEvent(const RefPtr<GestureEventHub> & gestureHub)442 bool SlidingPanelPattern::IsNeedResetPanEvent(const RefPtr<GestureEventHub>& gestureHub)
443 {
444     auto layoutProperty = GetLayoutProperty<SlidingPanelLayoutProperty>();
445     auto type = layoutProperty->GetPanelType().value_or(PanelType::FOLDABLE_BAR);
446     if (panEvent_) {
447         if (type == PanelType::CUSTOM) {
448             if (panEvent_->GetActionStartEventFunc()) {
449                 gestureHub->RemovePanEvent(panEvent_);
450                 panEvent_.Reset();
451             } else {
452                 return false;
453             }
454         } else {
455             if (panEvent_->GetActionStartEventFunc()) {
456                 return false;
457             } else {
458                 gestureHub->RemovePanEvent(panEvent_);
459                 panEvent_.Reset();
460             }
461         }
462     }
463     return true;
464 }
465 
HandleDragStart(const Offset & startPoint)466 void SlidingPanelPattern::HandleDragStart(const Offset& startPoint) // const GestureEvent& info
467 {
468     if (isAnimating_ || !isShow_.value_or(false)) {
469         return;
470     }
471     isDrag_ = true;
472     dragStartCurrentOffset_ = currentOffset_;
473 }
474 
HandleDragUpdate(const GestureEvent & info)475 void SlidingPanelPattern::HandleDragUpdate(const GestureEvent& info)
476 {
477     if (isAnimating_ || !isShow_.value_or(false)) {
478         return;
479     }
480     auto mainDelta = static_cast<float>(info.GetMainDelta());
481     auto host = GetHost();
482     CHECK_NULL_VOID(host);
483     auto geometryNode = host->GetGeometryNode();
484     CHECK_NULL_VOID(geometryNode);
485     auto tempOffset = currentOffset_;
486     UpdateCurrentOffset(mainDelta);
487     if (NearEqual(currentOffset_, tempOffset)) {
488         return;
489     }
490     FireHeightChangeEvent();
491     host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
492 }
493 
HandleDragEnd(float dragVelocity)494 void SlidingPanelPattern::HandleDragEnd(float dragVelocity)
495 {
496     if (isAnimating_ || !isShow_.value_or(false)) {
497         return;
498     }
499     isClosePanel_ = false;
500     auto dragLen = currentOffset_ - dragStartCurrentOffset_;
501     type_ = GetPanelType();
502     switch (type_) {
503         case PanelType::MINI_BAR: { // FULL & MINI
504             CalculateModeTypeMini(dragLen, dragVelocity);
505             break;
506         }
507         case PanelType::FOLDABLE_BAR: { // FULL & HALF & MINI
508             CalculateModeTypeFold(dragLen, dragVelocity);
509             break;
510         }
511         case PanelType::TEMP_DISPLAY: { // FULL & HALF
512             CalculateModeTypeTemp(dragLen, dragVelocity);
513             break;
514         }
515         default: {
516             return;
517         }
518     }
519     if (isClosePanel_) {
520         AnimateTo(maxSize_.Height(), mode_.value_or(PanelMode::HALF));
521         mode_ = PanelMode::AUTO;
522     } else {
523         AnimateTo(defaultBlankHeights_[mode_.value_or(PanelMode::HALF)], mode_.value_or(PanelMode::HALF));
524     }
525     if (previousMode_ != mode_.value_or(PanelMode::HALF)) {
526         FireSizeChangeEvent();
527         previousMode_ = mode_.value_or(PanelMode::HALF);
528     }
529     isDrag_ = false;
530 }
531 
CalculateModeTypeMini(float dragLen,float velocity)532 void SlidingPanelPattern::CalculateModeTypeMini(float dragLen, float velocity) // FULL & MINI
533 {
534     float currentPostion = currentOffset_;
535     if (std::abs(velocity) < VELOCITY_THRESHOLD) {
536         // Drag velocity not reached to threshold, mode based on the location.
537         if (currentPostion < fullMiniBoundary_) {
538             mode_ = PanelMode::FULL;
539         } else {
540             mode_ = PanelMode::MINI;
541         }
542     } else {
543         // Drag velocity reached to threshold, mode based on the drag direction.
544         if (velocity > 0.0) {
545             mode_ = PanelMode::MINI;
546         } else {
547             mode_ = PanelMode::FULL;
548         }
549     }
550 }
551 
CalculateModeTypeFold(float dragLen,float velocity)552 void SlidingPanelPattern::CalculateModeTypeFold(float dragLen, float velocity) // // FULL & HALF & MINI
553 {
554     float currentPostion = currentOffset_;
555     if (std::abs(velocity) < VELOCITY_THRESHOLD) {
556         // Drag velocity not reached to threshold, mode based on the location.
557         if (currentPostion < fullHalfBoundary_) {
558             mode_ = PanelMode::FULL;
559         } else if (currentPostion < halfMiniBoundary_) {
560             mode_ = PanelMode::HALF;
561         } else {
562             mode_ = PanelMode::MINI;
563         }
564     } else {
565         // Drag velocity reached to threshold, mode based on the drag direction.
566         if (velocity > 0.0) {
567             if (currentPostion < defaultBlankHeights_[PanelMode::HALF]) {
568                 mode_ = PanelMode::HALF;
569             } else {
570                 mode_ = PanelMode::MINI;
571             }
572         } else {
573             if (currentPostion > defaultBlankHeights_[PanelMode::HALF]) {
574                 mode_ = PanelMode::HALF;
575             } else {
576                 mode_ = PanelMode::FULL;
577             }
578         }
579     }
580 }
581 
CalculateModeTypeTemp(float dragLen,float velocity)582 void SlidingPanelPattern::CalculateModeTypeTemp(float dragLen, float velocity) // FULL & HALF
583 {
584     float currentPostion = currentOffset_;
585     float halfCloseBoundary = (defaultBlankHeights_[PanelMode::HALF] + maxSize_.Height()) / 2.0f;
586     if (std::abs(velocity) < VELOCITY_THRESHOLD) {
587         // Drag velocity not reached to threshold, mode based on the location.
588         if (currentPostion < fullHalfBoundary_) {
589             mode_ = PanelMode::FULL;
590         } else if (currentPostion < halfCloseBoundary) {
591             mode_ = PanelMode::HALF;
592         } else {
593             isClosePanel_ = true;
594         }
595     } else {
596         // Drag velocity reached to threshold, mode based on the drag direction.
597         if (velocity > 0.0) {
598             if (currentPostion < defaultBlankHeights_[PanelMode::HALF]) {
599                 mode_ = PanelMode::HALF;
600             } else {
601                 isClosePanel_ = true;
602             }
603         } else {
604             if (currentPostion > defaultBlankHeights_[PanelMode::HALF]) {
605                 mode_ = PanelMode::HALF;
606             } else {
607                 mode_ = PanelMode::FULL;
608             }
609         }
610     }
611 
612     if (dragLen > 0 && mode_ == PanelMode::HALF) {
613         isClosePanel_ = true;
614     }
615 }
616 
AnimateTo(float targetLocation,PanelMode mode)617 void SlidingPanelPattern::AnimateTo(float targetLocation, PanelMode mode)
618 {
619     auto host = GetHost();
620     CHECK_NULL_VOID(host);
621     animator_ = CREATE_ANIMATOR(host->GetContextRefPtr());
622     isAnimating_ = true;
623     animator_->ClearInterpolators();
624     animator_->ClearAllListeners();
625     animator_->SetExpectedFrameRateRange(FrameRateRange(FRAME_RATE, FRAME_RATE, FRAME_RATE));
626     if (animator_->IsRunning()) {
627         animator_->Stop();
628     }
629     animator_->AddStopListener([weak = WeakClaim(this), mode]() {
630         auto panel = weak.Upgrade();
631         CHECK_NULL_VOID(panel);
632         auto layoutProperty = panel->GetLayoutProperty<SlidingPanelLayoutProperty>();
633         CHECK_NULL_VOID(layoutProperty);
634         if (layoutProperty->GetHasDragBarValue(true)) {
635             auto dragBar = panel->GetDragBarNode();
636             CHECK_NULL_VOID(dragBar);
637             auto dragBarPattern = dragBar->GetPattern<DragBarPattern>();
638             CHECK_NULL_VOID(dragBarPattern);
639             dragBarPattern->ShowInPanelMode(mode);
640         }
641         if (!panel->isShowQueue_.empty() && !panel->isShowQueue_.front()) {
642             auto panelNode = panel->GetHost();
643             panel->invisibleFlag_ = true;
644             panelNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
645         }
646         auto host = panel->GetHost();
647         CHECK_NULL_VOID(host);
648         AceAsyncTraceEnd(
649             0, (TRAILING_ANIMATION + std::to_string(host->GetAccessibilityId()) + std::string(" ") + host->GetTag())
650                 .c_str());
651         panel->OnAnimationStop();
652         panel->preAnimateFlag_ = false;
653     });
654     AppendBlankHeightAnimation(targetLocation, mode);
655     auto geometryNode = host->GetGeometryNode();
656     auto frameSize = geometryNode->GetFrameSize();
657     auto dragRange = frameSize.Height();
658     animator_->SetDuration(GetAnimationDuration(targetLocation - currentOffset_, dragRange)); // inner
659     animator_->SetFillMode(FillMode::FORWARDS);
660     animator_->Forward();
661 }
662 
AppendBlankHeightAnimation(float targetLocation,PanelMode mode)663 void SlidingPanelPattern::AppendBlankHeightAnimation(float targetLocation, PanelMode mode)
664 {
665     auto springProperty = AceType::MakeRefPtr<SpringProperty>(1.0f, 100.0f, 20.0f);
666     auto heightAnimation = AceType::MakeRefPtr<SpringAnimation>(springProperty);
667     heightAnimation->AddListener(
668         [weak = AceType::WeakClaim(this), start = currentOffset_, end = targetLocation, mode](float value) {
669             auto panel = weak.Upgrade();
670             if (!panel) {
671                 return;
672             }
673             if (value > 1.0) {
674                 auto layoutProperty = panel->GetLayoutProperty<SlidingPanelLayoutProperty>();
675                 CHECK_NULL_VOID(layoutProperty);
676                 if (layoutProperty->GetHasDragBarValue(true)) {
677                     auto dragBar = panel->GetDragBarNode();
678                     CHECK_NULL_VOID(dragBar);
679                     auto dragBarPattern = dragBar->GetPattern<DragBarPattern>();
680                     CHECK_NULL_VOID(dragBarPattern);
681                     dragBarPattern->ShowInPanelMode(mode);
682                 }
683             }
684             auto currentOffset = (end - start) * value + start;
685             auto lastOffset = panel->GetLastOffset();
686             auto host = panel->GetHost();
687             CHECK_NULL_VOID(host);
688             if (NearEqual(currentOffset, lastOffset, 1.0)) {
689                 AceAsyncTraceBegin(0, (TRAILING_ANIMATION + std::to_string(host->GetAccessibilityId()) +
690                                           std::string(" ") + host->GetTag())
691                                           .c_str());
692             }
693             panel->SetLastOffset(currentOffset);
694             panel->UpdateCurrentOffsetOnAnimate(currentOffset);
695             panel->FireHeightChangeEvent();
696             panel->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
697         });
698     animator_->AddInterpolator(heightAnimation);
699 }
700 
GetDragBarNode()701 RefPtr<FrameNode> SlidingPanelPattern::GetDragBarNode()
702 {
703     auto column = GetChildNodeByTag(V2::COLUMN_ETS_TAG);
704     CHECK_NULL_RETURN(column, nullptr);
705     auto dragBar = AceType::DynamicCast<FrameNode>(column->GetChildAtIndex(0));
706     return dragBar;
707 }
708 
GetCloseIconNode()709 RefPtr<FrameNode> SlidingPanelPattern::GetCloseIconNode()
710 {
711     auto closeIcon = GetChildNodeByTag(V2::PANEL_CLOSE_ICON_ETS_TAG);
712     CHECK_NULL_RETURN(closeIcon, nullptr);
713     return AceType::DynamicCast<FrameNode>(closeIcon);
714 }
715 
GetAnimationDuration(float delta,float dragRange) const716 int32_t SlidingPanelPattern::GetAnimationDuration(float delta, float dragRange) const
717 {
718     if (NearZero(dragRange)) {
719         return 0;
720     }
721     // duration is in millisecond
722     return static_cast<int32_t>(((std::abs(delta) / dragRange) + 1.0) * ANIMATION_BASE_DURATION);
723 }
724 
OnAnimationStop()725 void SlidingPanelPattern::OnAnimationStop()
726 {
727     if (!isShowQueue_.empty()) {
728         isShowQueue_.pop();
729         if (!isShowQueue_.empty() && isShowQueue_.front()) {
730             invisibleFlag_ = false;
731             auto host = GetHost();
732             host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
733         }
734     }
735     isAnimating_ = false;
736 }
737 
UpdateCurrentOffset(float offset)738 void SlidingPanelPattern::UpdateCurrentOffset(float offset)
739 {
740     auto host = GetHost();
741     CHECK_NULL_VOID(host);
742     currentOffset_ = currentOffset_ + offset;
743     currentOffset_ = currentOffset_ <= static_cast<float>(BLANK_MIN_HEIGHT.ConvertToPx())
744                          ? static_cast<float>(BLANK_MIN_HEIGHT.ConvertToPx())
745                          : currentOffset_;
746     host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
747 }
748 
UpdateCurrentOffsetOnAnimate(float currentOffset)749 void SlidingPanelPattern::UpdateCurrentOffsetOnAnimate(float currentOffset)
750 {
751     auto host = GetHost();
752     CHECK_NULL_VOID(host);
753     currentOffset_ = currentOffset;
754     currentOffset_ = currentOffset_ <= static_cast<float>(BLANK_MIN_HEIGHT.ConvertToPx())
755                          ? static_cast<float>(BLANK_MIN_HEIGHT.ConvertToPx())
756                          : currentOffset_;
757     host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
758 }
759 
GetPanelType() const760 PanelType SlidingPanelPattern::GetPanelType() const
761 {
762     auto slidingLayoutProperty = GetLayoutProperty<SlidingPanelLayoutProperty>();
763     CHECK_NULL_RETURN(slidingLayoutProperty, PanelType::FOLDABLE_BAR);
764     return slidingLayoutProperty->GetPanelType().value_or(PanelType::FOLDABLE_BAR);
765 }
766 
GetPanelMode() const767 PanelMode SlidingPanelPattern::GetPanelMode() const
768 {
769     auto slidingLayoutProperty = GetLayoutProperty<SlidingPanelLayoutProperty>();
770     CHECK_NULL_RETURN(slidingLayoutProperty, PanelMode::HALF);
771     return slidingLayoutProperty->GetPanelMode().value_or(PanelMode::HALF);
772 }
773 
FireSizeChangeEvent()774 void SlidingPanelPattern::FireSizeChangeEvent()
775 {
776     auto slidingPanelEventHub = GetEventHub<SlidingPanelEventHub>();
777     CHECK_NULL_VOID(slidingPanelEventHub);
778     auto host = GetHost();
779     CHECK_NULL_VOID(host);
780     auto frameSize = host->GetGeometryNode()->GetFrameSize();
781     auto layoutProperty = GetLayoutProperty<SlidingPanelLayoutProperty>();
782     CHECK_NULL_VOID(layoutProperty);
783     float height = 0.0f;
784     if (layoutProperty->GetHasDragBarValue(true)) {
785         auto dragBar = GetDragBarNode();
786         CHECK_NULL_VOID(dragBar);
787         auto dragBarFrameSize = dragBar->GetGeometryNode()->GetFrameSize();
788         height = std::floor(
789             frameSize.Height() - defaultBlankHeights_[mode_.value_or(PanelMode::HALF)] - dragBarFrameSize.Height());
790     } else {
791         height = std::floor(frameSize.Height() - defaultBlankHeights_[mode_.value_or(PanelMode::HALF)]);
792     }
793     slidingPanelEventHub->FireSizeChangeEvent(mode_.value_or(PanelMode::HALF), maxWidth_, height);
794     previousMode_ = mode_.value_or(PanelMode::HALF);
795 }
796 
FireHeightChangeEvent()797 void SlidingPanelPattern::FireHeightChangeEvent()
798 {
799     auto slidingPanelEventHub = GetEventHub<SlidingPanelEventHub>();
800     CHECK_NULL_VOID(slidingPanelEventHub);
801     auto host = GetHost();
802     CHECK_NULL_VOID(host);
803     auto geometryNode = host->GetGeometryNode();
804     CHECK_NULL_VOID(geometryNode);
805 
806     auto layoutProperty = GetLayoutProperty<SlidingPanelLayoutProperty>();
807     CHECK_NULL_VOID(layoutProperty);
808     auto currentHeight = 0.0f;
809     if (layoutProperty->GetHasDragBarValue(true)) {
810         auto dragBar = GetDragBarNode();
811         CHECK_NULL_VOID(dragBar);
812         auto dragBarFrameSize = dragBar->GetGeometryNode()->GetFrameSize();
813         currentHeight =
814             static_cast<float>(geometryNode->GetFrameSize().Height() - currentOffset_ - dragBarFrameSize.Height());
815     } else {
816         currentHeight = static_cast<float>(geometryNode->GetFrameSize().Height() - currentOffset_);
817     }
818 
819     slidingPanelEventHub->FireHeightChangeEvent(currentHeight);
820 }
821 
SetDragBarCallBack()822 void SlidingPanelPattern::SetDragBarCallBack()
823 {
824     auto dragBar = GetDragBarNode();
825     CHECK_NULL_VOID(dragBar);
826     auto dragBarPattern = dragBar->GetPattern<DragBarPattern>();
827     CHECK_NULL_VOID(dragBarPattern);
828     dragBarPattern->SetClickArrowCallback([weak = WeakClaim(this)]() {
829         auto panel = weak.Upgrade();
830         CHECK_NULL_VOID(panel);
831         panel->previousMode_ = panel->mode_.value_or(PanelMode::HALF);
832         if (panel->previousMode_ == PanelMode::HALF) {
833             return;
834         }
835         if (panel->mode_.value_or(PanelMode::HALF) == PanelMode::MINI) {
836             panel->mode_ = panel->type_ == PanelType::MINI_BAR ? PanelMode::FULL : PanelMode::HALF;
837         } else if (panel->mode_.value_or(PanelMode::HALF) == PanelMode::FULL) {
838             panel->mode_ = panel->type_ == PanelType::MINI_BAR ? PanelMode::MINI : PanelMode::HALF;
839         } else {
840         }
841         if (panel->type_ == PanelType::TEMP_DISPLAY && panel->mode_ == PanelMode::HALF) {
842             panel->isClosePanel_ = true;
843             panel->AnimateTo(panel->maxSize_.Height(), panel->mode_.value_or(PanelMode::HALF));
844             panel->mode_ = PanelMode::AUTO;
845         } else {
846             panel->isClosePanel_ = false;
847             panel->AnimateTo(panel->defaultBlankHeights_[panel->mode_.value_or(PanelMode::HALF)],
848                 panel->mode_.value_or(PanelMode::HALF));
849         }
850         if (panel->previousMode_ != panel->mode_.value_or(PanelMode::HALF)) {
851             panel->FireSizeChangeEvent();
852         }
853     });
854 }
855 
SetCloseIconCallBack()856 void SlidingPanelPattern::SetCloseIconCallBack()
857 {
858     auto closeIconNode = GetCloseIconNode();
859     CHECK_NULL_VOID(closeIconNode);
860     auto closeIconPattern = closeIconNode->GetPattern<CloseIconPattern>();
861     CHECK_NULL_VOID(closeIconPattern);
862     closeIconPattern->SetClickButtonCallback([weak = WeakClaim(this)]() {
863         auto pattern = weak.Upgrade();
864         CHECK_NULL_VOID(pattern);
865         auto host = pattern->GetHost();
866         pattern->isClosePanel_ = true;
867         pattern->AnimateTo(pattern->maxSize_.Height(), pattern->mode_.value_or(PanelMode::HALF));
868         pattern->mode_ = PanelMode::AUTO;
869         pattern->FireSizeChangeEvent();
870     });
871 }
872 
MarkDirtyNode(PropertyChangeFlag extraFlag)873 void SlidingPanelPattern::MarkDirtyNode(PropertyChangeFlag extraFlag)
874 {
875     auto host = GetHost();
876     CHECK_NULL_VOID(host);
877     host->MarkDirtyNode(extraFlag);
878 }
879 
ToJsonValue(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter) const880 void SlidingPanelPattern::ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const
881 {
882     Pattern::ToJsonValue(json, filter);
883      /* no fixed attr below, just return */
884     if (filter.IsFastFilter()) {
885         return;
886     }
887     auto layoutProperty = GetLayoutProperty<SlidingPanelLayoutProperty>();
888     CHECK_NULL_VOID(layoutProperty);
889     static const char* PANEL_TYPE[] = { "PanelType.Minibar", "PanelType.Foldable", "PanelType.Temporary" };
890     json->PutExtAttr("type",
891         PANEL_TYPE[static_cast<int32_t>(layoutProperty->GetPanelType().value_or(PanelType::FOLDABLE_BAR))], filter);
892     static const char* PANEL_MODE[] = { "PanelMode.Mini", "PanelMode.Half", "PanelMode.Full" };
893     json->PutExtAttr("mode",
894         PANEL_MODE[static_cast<int32_t>(layoutProperty->GetPanelMode().value_or(PanelMode::HALF))], filter);
895     json->PutExtAttr("dragBar", layoutProperty->GetHasDragBar().value_or(true) ? "true" : "false", filter);
896     json->PutExtAttr("show", layoutProperty->GetIsShow().value_or(true) ? "true" : "false", filter);
897     json->PutExtAttr("miniHeight",
898         layoutProperty->GetMiniHeight().value_or(miniHeight_).ToString().c_str(), filter);
899     json->PutExtAttr("halfHeight",
900         layoutProperty->GetHalfHeight().value_or(halfHeight_).ToString().c_str(), filter);
901     json->PutExtAttr("fullHeight",
902         layoutProperty->GetFullHeight().value_or(fullHeight_).ToString().c_str(), filter);
903     json->PutExtAttr("customHeight",
904         layoutProperty->GetFullHeight().value_or(customHeight_).ToString().c_str(), filter);
905     json->PutExtAttr("backgroundMask",
906         layoutProperty->GetBackgroundColor().value_or(Color::TRANSPARENT).ColorToString().c_str(), filter);
907     json->PutExtAttr("showCloseIcon",
908         layoutProperty->GetShowCloseIcon().value_or(false) ? "true" : "false", filter);
909 }
910 
GetChildNodeByTag(const std::string & tagName) const911 RefPtr<UINode> SlidingPanelPattern::GetChildNodeByTag(const std::string& tagName) const
912 {
913     auto host = GetHost();
914     CHECK_NULL_RETURN(host, nullptr);
915     auto allChilds = host->GetChildren();
916     for (size_t index = 0; index < allChilds.size(); index++) {
917         auto tag = host->GetChildAtIndex(index)->GetTag();
918         if (tag == tagName) {
919             return host->GetChildAtIndex(index);
920         }
921     }
922     return nullptr;
923 }
924 
AddOrRemoveDragBarNode(const RefPtr<SlidingPanelLayoutProperty> & layoutProperty) const925 void SlidingPanelPattern::AddOrRemoveDragBarNode(const RefPtr<SlidingPanelLayoutProperty>& layoutProperty) const
926 {
927     CHECK_NULL_VOID(layoutProperty);
928     auto isHasDragBar = layoutProperty->GetHasDragBar().value_or(true);
929     auto columnNode = GetChildNodeByTag(V2::COLUMN_ETS_TAG);
930     CHECK_NULL_VOID(columnNode);
931     auto child = columnNode->GetChildren();
932     bool isFirstChildDragBar = false;
933     if (!child.empty()) {
934         auto firstNode = columnNode->GetChildren().front();
935         isFirstChildDragBar = firstNode->GetTag() == V2::DRAG_BAR_ETS_TAG;
936     }
937     if (isHasDragBar && !isFirstChildDragBar) {
938         auto dragBarNode = FrameNode::GetOrCreateFrameNode(V2::DRAG_BAR_ETS_TAG,
939             ElementRegister::GetInstance()->MakeUniqueId(), []() { return AceType::MakeRefPtr<DragBarPattern>(); });
940         auto paintProperty = dragBarNode->GetPaintProperty<DragBarPaintProperty>();
941         CHECK_NULL_VOID(paintProperty);
942         auto panelMode = layoutProperty->GetPanelModeValue(PanelMode::HALF);
943         auto type = layoutProperty->GetPanelTypeValue(PanelType::FOLDABLE_BAR);
944         // This parameter does not take effect when PanelMode is set to Half and PanelType is set to minibar
945         if (panelMode == PanelMode::HALF && type == PanelType::MINI_BAR) {
946             panelMode = PanelMode::MINI;
947         }
948         // This parameter does not take effect when PanelMode is set to Mini and PanelType is set to temporary
949         if (panelMode == PanelMode::MINI && type == PanelType::TEMP_DISPLAY) {
950             panelMode = PanelMode::HALF;
951         }
952         paintProperty->UpdatePanelMode(panelMode);
953         auto dragBarPattern = dragBarNode->GetPattern<DragBarPattern>();
954         CHECK_NULL_VOID(dragBarPattern);
955         dragBarPattern->SetIsFirstUpdate(true);
956         dragBarNode->MountToParent(columnNode, 0);
957         dragBarNode->MarkModifyDone();
958     } else if (!isHasDragBar && isFirstChildDragBar) {
959         columnNode->RemoveChildAtIndex(0);
960     }
961 }
962 
AddOrRemoveCloseIconNode(const RefPtr<SlidingPanelLayoutProperty> & layoutProperty) const963 void SlidingPanelPattern::AddOrRemoveCloseIconNode(const RefPtr<SlidingPanelLayoutProperty>& layoutProperty) const
964 {
965     CHECK_NULL_VOID(layoutProperty);
966     auto isShowCloseIcon = layoutProperty->GetShowCloseIcon().value_or(false);
967     auto host = GetHost();
968     CHECK_NULL_VOID(host);
969     auto closeIcon = GetChildNodeByTag(V2::PANEL_CLOSE_ICON_ETS_TAG);
970     if (isShowCloseIcon && !closeIcon) {
971         auto closeIcon = FrameNode::GetOrCreateFrameNode(V2::PANEL_CLOSE_ICON_ETS_TAG,
972             ElementRegister::GetInstance()->MakeUniqueId(), []() { return AceType::MakeRefPtr<CloseIconPattern>(); });
973         auto closeIconLayoutProperty = closeIcon->GetLayoutProperty<CloseIconLayoutProperty>();
974         auto pipeline = PipelineContext::GetCurrentContext();
975         CHECK_NULL_VOID(pipeline);
976         auto closeIconTheme = pipeline->GetTheme<CloseIconTheme>();
977         closeIconLayoutProperty->UpdateCloseIconWidth(closeIconTheme->GetCloseIconWidth());
978         closeIconLayoutProperty->UpdateCloseIconHeight(closeIconTheme->GetCloseIconHeight());
979         closeIconLayoutProperty->UpdateCloseIconMarginTop(closeIconTheme->GetCloseIconMarginTop());
980         closeIconLayoutProperty->UpdateCloseIconMarginRight(closeIconTheme->GetCloseIconMarginRight());
981         closeIconLayoutProperty->UpdateCloseIconRadius(closeIconTheme->GetCloseIconRadius());
982         closeIcon->MountToParent(host, 1);
983         closeIcon->MarkModifyDone();
984     } else if (!isShowCloseIcon && closeIcon) {
985         host->RemoveChild(closeIcon);
986     }
987 }
988 
ResetLayoutWeight()989 void SlidingPanelPattern::ResetLayoutWeight()
990 {
991     auto columnNode = GetChildNodeByTag(V2::COLUMN_ETS_TAG);
992     CHECK_NULL_VOID(columnNode);
993     auto child = columnNode->GetChildren();
994     if (!child.empty()) {
995         auto firstNode = columnNode->GetChildren().front();
996         if (firstNode->GetTag() == V2::DRAG_BAR_ETS_TAG) {
997             firstNode = columnNode->GetChildAtIndex(1);
998         }
999         auto contentNode = DynamicCast<FrameNode>(firstNode);
1000         auto contentLayoutProperty = contentNode->GetLayoutProperty<LayoutProperty>();
1001         CHECK_NULL_VOID(contentLayoutProperty);
1002         contentLayoutProperty->UpdateLayoutWeight(0.0f);
1003     }
1004 }
1005 } // namespace OHOS::Ace::NG
1006