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