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/box/render_box.h"
17 
18 #include "base/log/event_report.h"
19 #include "core/components/box/box_component_helper.h"
20 #include "core/components/container_modal/container_modal_constants.h"
21 #include "core/components/text_field/render_text_field.h"
22 #include "core/components_v2/list/render_list.h"
23 #include "core/gestures/parallel_recognizer.h"
24 
25 namespace OHOS::Ace {
26 namespace {
27 
28 constexpr int32_t HOVER_ANIMATION_DURATION = 250;
29 
30 }; // namespace
31 
HandleAccessibilityFocusEvent(bool isAccessibilityFocus)32 void RenderBox::HandleAccessibilityFocusEvent(bool isAccessibilityFocus)
33 {
34     isAccessibilityFocus_ = isAccessibilityFocus;
35     std::string accessibilityEventType;
36     if (isAccessibilityFocus) {
37         accessibilityEventType = "accessibilityfocus";
38     } else {
39         accessibilityEventType = "accessibilityclearfocus";
40     }
41     SendAccessibilityEvent(accessibilityEventType);
42     MarkNeedRender();
43 }
44 
GetBorderSize() const45 Size RenderBox::GetBorderSize() const
46 {
47     auto context = GetContext().Upgrade();
48     if (backDecoration_ && context) {
49         return backDecoration_->GetBorder().GetLayoutSize(context->GetDipScale());
50     }
51     return Size(0.0, 0.0);
52 }
53 
GetBorderOffset() const54 Offset RenderBox::GetBorderOffset() const
55 {
56     auto context = GetContext().Upgrade();
57     if (backDecoration_ && context) {
58         return backDecoration_->GetBorder().GetOffset(context->GetDipScale());
59     }
60     return Offset(0.0, 0.0);
61 }
62 
GetBorderRadius() const63 Radius RenderBox::GetBorderRadius() const
64 {
65     if (backDecoration_) {
66         return backDecoration_->GetBorder().TopLeftRadius();
67     }
68     return Radius();
69 }
70 
Update(const RefPtr<Component> & component)71 void RenderBox::Update(const RefPtr<Component>& component)
72 {
73     const RefPtr<BoxComponent> box = AceType::DynamicCast<BoxComponent>(component);
74     if (box) {
75         boxComponent_ = box;
76         needMaterial_ |= box->GetNeedMaterial();
77         inspectorDirection_ = box->GetInspectorDirection();
78         RenderBoxBase::Update(component);
79         UpdateBackDecoration(box->GetBackDecoration());
80         needPaintDebugBoundary_ = box->GetEnableDebugBoundary();
81         UpdateFrontDecoration(box->GetFrontDecoration());
82         hoverColorBegin_ = box->GetColor();
83         hoverAnimationType_ = box->GetMouseAnimationType();
84         isZoom = hoverAnimationType_ == HoverAnimationType::SCALE;
85         MarkNeedLayout();
86 
87         responseRegion_ = box->GetResponseRegion();
88         isResponseRegion_ = box->IsResponseRegion();
89 
90         auto tapGesture = box->GetOnClick();
91         if (tapGesture) {
92             onClick_ = tapGesture->CreateRecognizer(context_);
93             onClick_->SetIsExternalGesture(true);
94             SetAccessibilityClickImpl();
95         } else {
96             onClick_ = nullptr;
97         }
98         if (!box->GetRemoteMessageEvent().IsEmpty() && !tapGesture) {
99             onClick_ = AceType::MakeRefPtr<ClickRecognizer>();
100         }
101         auto clickRecognizer = AceType::DynamicCast<ClickRecognizer>(onClick_);
102         if (clickRecognizer) {
103             auto weak = AceType::WeakClaim(this);
104             clickRecognizer->SetRemoteMessage([weak](const ClickInfo& info) {
105                 auto client = weak.Upgrade();
106                 if (client) {
107                     client->HandleRemoteMessage(info);
108                 }
109             });
110         }
111         auto longPressGesture = box->GetOnLongPress();
112         if (longPressGesture) {
113             onLongPress_ = longPressGesture->CreateRecognizer(context_);
114             onLongPress_->SetIsExternalGesture(true);
115         }
116 
117         onDragStart_ = box->GetOnDragStartId();
118         onDragEnter_ = box->GetOnDragEnterId();
119         onDragMove_ = box->GetOnDragMoveId();
120         onDragLeave_ = box->GetOnDragLeaveId();
121         onDrop_ = box->GetOnDropId();
122         enableDragStart_ = box->GetEnableDragStart();
123         if (onDragStart_) {
124             CreateDragDropRecognizer(context_);
125         }
126 
127         if (!box->GetOnDomDragEnter().IsEmpty()) {
128             onDomDragEnter_ = AceAsyncEvent<void(const DragUpdateInfo&)>::Create(box->GetOnDomDragEnter(), context_);
129         }
130         if (!box->GetOnDomDragOver().IsEmpty()) {
131             onDomDragOver_ = AceAsyncEvent<void(const DragUpdateInfo&)>::Create(box->GetOnDomDragOver(), context_);
132         }
133         if (!box->GetOnDomDragLeave().IsEmpty()) {
134             onDomDragLeave_ = AceAsyncEvent<void(const DragUpdateInfo&)>::Create(box->GetOnDomDragLeave(), context_);
135         }
136         if (!box->GetOnDomDragDrop().IsEmpty()) {
137             onDomDragDrop_ = AceAsyncEvent<void(const DragEndInfo&)>::Create(box->GetOnDomDragDrop(), context_);
138         }
139         if (!box->GetRemoteMessageEvent().IsEmpty()) {
140             remoteMessageEvent_ =
141                 AceAsyncEvent<void(const std::shared_ptr<ClickInfo>&)>::Create(box->GetRemoteMessageEvent(), context_);
142         }
143 
144         auto context = GetContext().Upgrade();
145         if (onDragStart_ || onDrop_) {
146             context->InitDragListener();
147         }
148 
149         onHover_ = box->GetOnHoverId();
150         onMouse_ = box->GetOnMouseId();
151         onLongPressId_ = box->GetOnLongPress();
152 
153         auto gestures = box->GetGestures();
154         UpdateGestureRecognizer(gestures);
155         SetAccessibilityFocusImpl();
156 
157         if (box->HasStateAttributes()) {
158             stateAttributeList_ = box->GetStateAttributes();
159         }
160         OnStatusStyleChanged(disabled_ ? VisualState::DISABLED : VisualState::NORMAL);
161 
162         onTouchUpId_ = box->GetOnTouchUpId();
163         onTouchDownId_ = box->GetOnTouchDownId();
164         onTouchMoveId_ = box->GetOnTouchMoveId();
165         auto wp = AceType::WeakClaim(this);
166         touchRecognizer_ = AceType::MakeRefPtr<RawRecognizer>();
167         touchRecognizer_->SetOnTouchDown([wp](const TouchEventInfo& touchInfo) {
168             auto box = wp.Upgrade();
169             if (!box) {
170                 return;
171             }
172             box->HandleTouchEvent(true);
173             if (box->onTouchDownId_) {
174                 box->onTouchDownId_(touchInfo);
175             }
176         });
177         touchRecognizer_->SetOnTouchUp([wp](const TouchEventInfo& touchInfo) {
178             auto box = wp.Upgrade();
179             if (!box) {
180                 return;
181             }
182             box->HandleTouchEvent(false);
183             if (box->onTouchUpId_) {
184                 box->onTouchUpId_(touchInfo);
185             }
186         });
187         touchRecognizer_->SetOnTouchMove(onTouchMoveId_);
188     }
189     // In each update, the extensions will be updated with new one.
190     if (eventExtensions_ && eventExtensions_->HasOnAreaChangeExtension()) {
191         auto inspector = inspector_.Upgrade();
192         if (inspector) {
193             auto area = inspector->GetCurrentRectAndOrigin();
194             auto lastArea = inspector->GetLastRectAndOrigin();
195             if (area != lastArea) {
196                 eventExtensions_->GetOnAreaChangeExtension()->UpdateArea(
197                     area.first, area.second, lastArea.first, lastArea.second);
198                 inspector->UpdateLastRectAndOrigin(area);
199             }
200         }
201     }
202 }
203 
HandleTouchEvent(bool isTouchDown)204 void RenderBox::HandleTouchEvent(bool isTouchDown)
205 {
206     if (isTouchDown) {
207         OnStatusStyleChanged(VisualState::PRESSED);
208     } else {
209         OnStatusStyleChanged(VisualState::NORMAL);
210     }
211 }
212 
SetAccessibilityFocusImpl()213 void RenderBox::SetAccessibilityFocusImpl()
214 {
215     auto refNode = accessibilityNode_.Upgrade();
216     if (!refNode) {
217         return;
218     }
219     auto weakPtr = AceType::WeakClaim(this);
220     refNode->SetActionAccessibilityFocusImpl([weakPtr](bool isFocus) {
221         auto accessibilityFocus = weakPtr.Upgrade();
222         if (accessibilityFocus) {
223             accessibilityFocus->HandleAccessibilityFocusEvent(isFocus);
224         }
225     });
226 }
227 
SetAccessibilityClickImpl()228 void RenderBox::SetAccessibilityClickImpl()
229 {
230     if (AceType::InstanceOf<ClickRecognizer>(onClick_)) {
231         auto clickRecognizer = AceType::DynamicCast<ClickRecognizer>(onClick_);
232         SetAccessibilityClick(clickRecognizer);
233     }
234 }
235 
AddDataToClipboard(const RefPtr<PipelineContext> & context,const std::string & extraInfo,const std::string & selectedText,const std::string & imageSrc)236 void RenderBox::AddDataToClipboard(const RefPtr<PipelineContext>& context, const std::string& extraInfo,
237     const std::string& selectedText, const std::string& imageSrc)
238 {
239     auto seleItemSizeStr = JsonUtil::Create(true);
240     seleItemSizeStr->Put("width", selectedItemSize_.Width());
241     seleItemSizeStr->Put("height", selectedItemSize_.Height());
242     seleItemSizeStr->Put("selectedIndex", selectedIndex_);
243     seleItemSizeStr->Put("customDragInfo", extraInfo.c_str());
244     MergeClipboardData(context, seleItemSizeStr->ToString());
245 }
246 
GenerateDragItemInfo(const RefPtr<PipelineContext> & context,const GestureEvent & info)247 DragItemInfo RenderBox::GenerateDragItemInfo(const RefPtr<PipelineContext>& context, const GestureEvent& info)
248 {
249     RefPtr<DragEvent> event = AceType::MakeRefPtr<DragEvent>();
250     event->SetX(context->ConvertPxToVp(Dimension(info.GetGlobalPoint().GetX(), DimensionUnit::PX)));
251     event->SetY(context->ConvertPxToVp(Dimension(info.GetGlobalPoint().GetY(), DimensionUnit::PX)));
252     selectedItemSize_ = GetLayoutSize();
253     auto extraParams = JsonUtil::Create(true);
254     SetSelectedIndex(info);
255     if (selectedIndex_ != DEFAULT_INDEX) {
256         extraParams->Put("selectedIndex", selectedIndex_);
257     }
258 
259     return onDragStart_(event, extraParams->ToString());
260 }
261 
PanOnActionStart(const GestureEvent & info)262 void RenderBox::PanOnActionStart(const GestureEvent& info)
263 {
264     if (!enableDragStart_) {
265         LOGI("drag start is disabled.");
266         return;
267     }
268 
269     if (!onDragStart_) {
270         return;
271     }
272 
273     auto pipelineContext = context_.Upgrade();
274     if (!pipelineContext) {
275         LOGE("Context is null.");
276         return;
277     }
278 
279     GestureEvent newInfo = info;
280     Point newPoint = UpdatePoint(pipelineContext, startPoint_);
281     newInfo.SetGlobalPoint(newPoint);
282     auto dragItemInfo = GenerateDragItemInfo(pipelineContext, newInfo);
283 #if !defined(PREVIEW)
284     if (dragItemInfo.pixelMap) {
285         auto initRenderNode = AceType::Claim(this);
286         isDragDropNode_  = true;
287         pipelineContext->SetInitRenderNode(initRenderNode);
288 
289         AddDataToClipboard(pipelineContext, dragItemInfo.extraInfo, "", "");
290         if (!dragWindow_) {
291             auto rect = pipelineContext->GetCurrentWindowRect();
292             dragWindow_ = DragWindow::CreateDragWindow("APP_DRAG_WINDOW",
293                 static_cast<int32_t>(info.GetGlobalPoint().GetX()) + rect.Left(),
294                 static_cast<int32_t>(info.GetGlobalPoint().GetY()) + rect.Top(), dragItemInfo.pixelMap->GetWidth(),
295                 dragItemInfo.pixelMap->GetHeight());
296             dragWindow_->SetOffset(rect.Left(), rect.Top());
297             dragWindow_->DrawPixelMap(dragItemInfo.pixelMap);
298         }
299         return;
300     }
301 #endif
302     if (!dragItemInfo.customComponent) {
303         LOGW("the drag custom component is null");
304         return;
305     }
306     hasDragItem_ = true;
307     auto positionedComponent = AceType::MakeRefPtr<PositionedComponent>(dragItemInfo.customComponent);
308     positionedComponent->SetTop(Dimension(GetGlobalOffset().GetY()));
309     positionedComponent->SetLeft(Dimension(GetGlobalOffset().GetX()));
310     SetLocalPoint(startPoint_ - GetGlobalOffset());
311     auto updatePosition = [renderBox = AceType::Claim(this)](
312                                 const std::function<void(const Dimension&, const Dimension&)>& func) {
313         if (!renderBox) {
314             return;
315         }
316         renderBox->SetUpdateBuilderFuncId(func);
317     };
318     positionedComponent->SetUpdatePositionFuncId(updatePosition);
319     auto stackElement = pipelineContext->GetLastStack();
320     stackElement->PushComponent(positionedComponent);
321 }
322 
PanOnActionUpdate(const GestureEvent & info)323 void RenderBox::PanOnActionUpdate(const GestureEvent& info)
324 {
325 #if !defined(PREVIEW)
326     if (isDragDropNode_  && dragWindow_) {
327         int32_t x = static_cast<int32_t>(info.GetGlobalPoint().GetX());
328         int32_t y = static_cast<int32_t>(info.GetGlobalPoint().GetY());
329         if (dragWindow_) {
330             dragWindow_->MoveTo(x, y);
331         }
332         return;
333     }
334 #endif
335     auto pipelineContext = context_.Upgrade();
336     if (!pipelineContext) {
337         LOGE("Context is null.");
338         return;
339     }
340     RefPtr<DragEvent> event = AceType::MakeRefPtr<DragEvent>();
341     auto isContainerModal = pipelineContext->GetWindowModal() == WindowModal::CONTAINER_MODAL &&
342         pipelineContext->GetWindowManager()->GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING;
343     if (isContainerModal) {
344         auto floatOffset =
345             info.GetGlobalPoint() + Offset(-(CONTAINER_BORDER_WIDTH.ConvertToPx() + CONTENT_PADDING.ConvertToPx()),
346             -CONTAINER_TITLE_HEIGHT.ConvertToPx());
347         event->SetX(pipelineContext->ConvertPxToVp(Dimension(floatOffset.GetX(), DimensionUnit::PX)));
348         event->SetY(pipelineContext->ConvertPxToVp(Dimension(floatOffset.GetY(), DimensionUnit::PX)));
349     } else {
350         event->SetX(pipelineContext->ConvertPxToVp(Dimension(info.GetGlobalPoint().GetX(), DimensionUnit::PX)));
351         event->SetY(pipelineContext->ConvertPxToVp(Dimension(info.GetGlobalPoint().GetY(), DimensionUnit::PX)));
352     }
353     Offset offset = info.GetGlobalPoint() - GetLocalPoint();
354     if (GetUpdateBuilderFuncId()) {
355         GetUpdateBuilderFuncId()(Dimension(offset.GetX()), Dimension(offset.GetY()));
356     }
357 
358     auto extraParams = JsonUtil::Create(true);
359     auto targetDragDropNode = FindDragDropNode(pipelineContext, info);
360     auto preDragDropNode = GetPreDragDropNode();
361     GestureEvent newInfo = info;
362     Point newPoint = UpdatePoint(pipelineContext, info.GetGlobalPoint());
363     newInfo.SetGlobalPoint(newPoint);
364     SetInsertIndex(targetDragDropNode, newInfo);
365     if (targetDragDropNode != initialDragDropNode_) {
366         extraParams->Put("selectedIndex", DEFAULT_INDEX_VALUE);
367     } else {
368         extraParams->Put("selectedIndex", selectedIndex_);
369     }
370     extraParams->Put("insertIndex", insertIndex_);
371     if (preDragDropNode == targetDragDropNode) {
372         if (targetDragDropNode && targetDragDropNode->GetOnDragMove()) {
373             (targetDragDropNode->GetOnDragMove())(event, extraParams->ToString());
374         }
375         return;
376     }
377     if (preDragDropNode && preDragDropNode->GetOnDragLeave()) {
378         (preDragDropNode->GetOnDragLeave())(event, extraParams->ToString());
379     }
380     if (targetDragDropNode && targetDragDropNode->GetOnDragEnter()) {
381         (targetDragDropNode->GetOnDragEnter())(event, extraParams->ToString());
382     }
383     SetPreDragDropNode(targetDragDropNode);
384 }
385 
PanOnActionEnd(const GestureEvent & info)386 void RenderBox::PanOnActionEnd(const GestureEvent& info)
387 {
388     auto pipelineContext = context_.Upgrade();
389     if (!pipelineContext) {
390         LOGE("Context is null.");
391         return;
392     }
393 #if !defined(PREVIEW)
394     if (isDragDropNode_) {
395         isDragDropNode_  = false;
396         RestoreCilpboardData(pipelineContext);
397 
398         if (GetOnDrop()) {
399             RefPtr<DragEvent> event = AceType::MakeRefPtr<DragEvent>();
400             RefPtr<PasteData> pasteData = AceType::MakeRefPtr<PasteData>();
401             event->SetPasteData(pasteData);
402             event->SetX(pipelineContext->ConvertPxToVp(Dimension(info.GetGlobalPoint().GetX(), DimensionUnit::PX)));
403             event->SetY(pipelineContext->ConvertPxToVp(Dimension(info.GetGlobalPoint().GetY(), DimensionUnit::PX)));
404 
405             auto extraParams = JsonUtil::Create(true);
406             extraParams->Put("selectedIndex", selectedIndex_);
407             extraParams->Put("insertIndex", insertIndex_);
408             (GetOnDrop())(event, extraParams->ToString());
409             pipelineContext->SetInitRenderNode(nullptr);
410         }
411     }
412 
413     if (dragWindow_) {
414         dragWindow_->Destroy();
415         dragWindow_ = nullptr;
416         return;
417     }
418 #endif
419     RefPtr<DragEvent> event = AceType::MakeRefPtr<DragEvent>();
420     RefPtr<PasteData> pasteData = AceType::MakeRefPtr<PasteData>();
421     event->SetPasteData(pasteData);
422     event->SetX(pipelineContext->ConvertPxToVp(Dimension(info.GetGlobalPoint().GetX(), DimensionUnit::PX)));
423     event->SetY(pipelineContext->ConvertPxToVp(Dimension(info.GetGlobalPoint().GetY(), DimensionUnit::PX)));
424 
425     Offset offset = info.GetGlobalPoint() - GetLocalPoint();
426     if (GetUpdateBuilderFuncId()) {
427         GetUpdateBuilderFuncId()(Dimension(offset.GetX()), Dimension(offset.GetY()));
428     }
429     if (hasDragItem_) {
430         auto stackElement = pipelineContext->GetLastStack();
431         stackElement->PopComponent();
432     }
433     hasDragItem_ = false;
434 
435     ACE_DCHECK(GetPreDragDropNode() == FindTargetRenderNode<RenderBox>(pipelineContext, info));
436     auto targetDragDropNode = GetPreDragDropNode();
437     if (!targetDragDropNode) {
438         return;
439     }
440     if (targetDragDropNode->GetOnDrop()) {
441         auto extraParams = JsonUtil::Create(true);
442         GestureEvent newInfo = info;
443         Point newPoint = UpdatePoint(pipelineContext, info.GetGlobalPoint());
444         newInfo.SetGlobalPoint(newPoint);
445         SetInsertIndex(targetDragDropNode, newInfo);
446         if (insertIndex_ == DEFAULT_INDEX_VALUE) {
447             (targetDragDropNode->GetOnDrop())(event, extraParams->ToString());
448             SetPreDragDropNode(nullptr);
449             return;
450         }
451         if (targetDragDropNode != initialDragDropNode_) {
452             extraParams->Put("selectedIndex", DEFAULT_INDEX_VALUE);
453         } else {
454             extraParams->Put("selectedIndex", selectedIndex_);
455         }
456         extraParams->Put("insertIndex", insertIndex_);
457         (targetDragDropNode->GetOnDrop())(event, extraParams->ToString());
458     }
459     SetPreDragDropNode(nullptr);
460 }
461 
PanOnActionCancel()462 void RenderBox::PanOnActionCancel()
463 {
464     auto pipelineContext = context_.Upgrade();
465     if (!pipelineContext) {
466         LOGE("Context is null.");
467         return;
468     }
469 
470 #if !defined(PREVIEW)
471     if (isDragDropNode_) {
472         RestoreCilpboardData(pipelineContext);
473         isDragDropNode_ = false;
474     }
475 
476     if (dragWindow_) {
477         dragWindow_->Destroy();
478         dragWindow_ = nullptr;
479     }
480 #endif
481     if (hasDragItem_) {
482         auto stackElement = pipelineContext->GetLastStack();
483         stackElement->PopComponent();
484         hasDragItem_ = false;
485     }
486     SetPreDragDropNode(nullptr);
487 }
488 
SetSelectedIndex(const GestureEvent & info)489 void RenderBox::SetSelectedIndex(const GestureEvent& info)
490 {
491     auto renderList = FindTargetRenderNode<V2::RenderList>(context_.Upgrade(), info);
492     if (renderList) {
493         selectedIndex_ = renderList->CalculateSelectedIndex(renderList, info, selectedItemSize_);
494         initialDragDropNode_ = FindDragDropNode(context_.Upgrade(), info);
495     }
496 }
497 
SetInsertIndex(const RefPtr<DragDropEvent> & targetDragDropNode,const GestureEvent & info)498 void RenderBox::SetInsertIndex(const RefPtr<DragDropEvent>& targetDragDropNode, const GestureEvent& info)
499 {
500     auto renderNode = AceType::DynamicCast<RenderNode>(targetDragDropNode);
501     if (!renderNode) {
502         insertIndex_ = DEFAULT_INDEX_VALUE;
503         return;
504     }
505     auto renderList = renderNode->FindTargetRenderNode<V2::RenderList>(context_.Upgrade(), info);
506     if (renderList) {
507         insertIndex_ = renderList->CalculateInsertIndex(renderList, info, selectedItemSize_);
508     }
509 }
510 
UpdateBackDecoration(const RefPtr<Decoration> & newDecoration)511 void RenderBox::UpdateBackDecoration(const RefPtr<Decoration>& newDecoration)
512 {
513     if (!newDecoration) {
514         backDecoration_ = newDecoration;
515         OnAttachContext();
516         return;
517     }
518 
519     if (!backDecoration_) {
520         backDecoration_ = AceType::MakeRefPtr<Decoration>();
521     }
522     OnAttachContext();
523 
524     backDecoration_->SetAnimationColor(newDecoration->GetAnimationColor());
525     backDecoration_->SetArcBackground(newDecoration->GetArcBackground());
526     backDecoration_->SetBlurRadius(newDecoration->GetBlurRadius());
527     backDecoration_->SetBorder(newDecoration->GetBorder());
528     backDecoration_->SetGradient(newDecoration->GetGradient(), context_, [weak = WeakClaim(this)] {
529         auto renderBox = weak.Upgrade();
530         if (renderBox) {
531             renderBox->OnAnimationCallback();
532         }
533     });
534     backDecoration_->SetBorderImageGradient(newDecoration->GetBorderImageGradient());
535     backDecoration_->SetHasBorderImageSource(newDecoration->GetHasBorderImageSource());
536     backDecoration_->SetHasBorderImageSlice(newDecoration->GetHasBorderImageSlice());
537     backDecoration_->SetHasBorderImageWidth(newDecoration->GetHasBorderImageWidth());
538     backDecoration_->SetHasBorderImageOutset(newDecoration->GetHasBorderImageOutset());
539     backDecoration_->SetHasBorderImageRepeat(newDecoration->GetHasBorderImageRepeat());
540     backDecoration_->SetHasBorderImageGradient(newDecoration->GetHasBorderImageGradient());
541     backDecoration_->SetImage(newDecoration->GetImage());
542     backDecoration_->SetBorderImage(newDecoration->GetBorderImage());
543     backDecoration_->SetPadding(newDecoration->GetPadding());
544     backDecoration_->SetWindowBlurProgress(newDecoration->GetWindowBlurProgress());
545     backDecoration_->SetWindowBlurStyle(newDecoration->GetWindowBlurStyle());
546     backDecoration_->SetShadows(newDecoration->GetShadows());
547     backDecoration_->SetGrayScale(newDecoration->GetGrayScale());
548     backDecoration_->SetBrightness(newDecoration->GetBrightness());
549     backDecoration_->SetContrast(newDecoration->GetContrast());
550     backDecoration_->SetSaturate(newDecoration->GetSaturate());
551     backDecoration_->SetInvert(newDecoration->GetInvert());
552     backDecoration_->SetColorBlend(newDecoration->GetColorBlend());
553     backDecoration_->SetSepia(newDecoration->GetSepia());
554     backDecoration_->SetBackgroundColor(newDecoration->GetBackgroundColor());
555     backDecoration_->SetBlurStyle(newDecoration->GetBlurStyle());
556 }
557 
UpdateFrontDecoration(const RefPtr<Decoration> & newDecoration)558 void RenderBox::UpdateFrontDecoration(const RefPtr<Decoration>& newDecoration)
559 {
560     if (!newDecoration) {
561         frontDecoration_ = newDecoration;
562         return;
563     }
564 
565     if (!frontDecoration_) {
566         frontDecoration_ = AceType::MakeRefPtr<Decoration>();
567     }
568     frontDecoration_->SetBlurRadius(newDecoration->GetBlurRadius());
569     frontDecoration_->SetBorder(newDecoration->GetBorder());
570     frontDecoration_->SetImage(newDecoration->GetImage());
571     frontDecoration_->SetShadows(newDecoration->GetShadows());
572     frontDecoration_->SetBackgroundColor(newDecoration->GetBackgroundColor());
573     frontDecoration_->SetGrayScale(newDecoration->GetGrayScale());
574     frontDecoration_->SetBrightness(newDecoration->GetBrightness());
575     frontDecoration_->SetContrast(newDecoration->GetContrast());
576     frontDecoration_->SetSaturate(newDecoration->GetSaturate());
577     frontDecoration_->SetInvert(newDecoration->GetInvert());
578     frontDecoration_->SetColorBlend(newDecoration->GetColorBlend());
579     frontDecoration_->SetSepia(newDecoration->GetSepia());
580     frontDecoration_->SetHueRotate(newDecoration->GetHueRotate());
581 }
582 
UpdateStyleFromRenderNode(PropertyAnimatableType type)583 void RenderBox::UpdateStyleFromRenderNode(PropertyAnimatableType type)
584 {
585     // Operator map for styles
586     static const std::unordered_map<PropertyAnimatableType, void (*)(RenderBox&)> operators = {
587         // Set width and height
588         { PropertyAnimatableType::PROPERTY_WIDTH,
589             [](RenderBox& node) {
590                 auto box = node.boxComponent_.Upgrade();
591                 if (box) {
592                     box->SetWidth(node.width_);
593                 }
594             } },
595         { PropertyAnimatableType::PROPERTY_HEIGHT,
596             [](RenderBox& node) {
597                 auto box = node.boxComponent_.Upgrade();
598                 if (box) {
599                     box->SetHeight(node.height_);
600                 }
601             } },
602         { PropertyAnimatableType::PROPERTY_BACK_DECORATION_COLOR,
603             [](RenderBox& node) {
604                 auto box = node.boxComponent_.Upgrade();
605                 if (box) {
606                     box->SetColor(node.GetColor());
607                 }
608             } },
609     };
610     auto operatorIter = operators.find(type);
611     if (operatorIter != operators.end()) {
612         operatorIter->second(*this);
613     }
614 }
615 
OnPaintFinish()616 void RenderBox::OnPaintFinish()
617 {
618     if (eventExtensions_ && eventExtensions_->HasOnAreaChangeExtension()) {
619         auto inspector = inspector_.Upgrade();
620         if (inspector) {
621             auto area = inspector->GetCurrentRectAndOrigin();
622             auto lastArea = inspector->GetLastRectAndOrigin();
623             if (area != lastArea) {
624                 eventExtensions_->GetOnAreaChangeExtension()->UpdateArea(
625                     area.first, area.second, lastArea.first, lastArea.second);
626                 inspector->UpdateLastRectAndOrigin(area);
627             }
628         }
629     }
630     auto node = GetAccessibilityNode().Upgrade();
631     if (!node) {
632         return;
633     }
634     if (!node->GetVisible()) { // Set 0 to item when whole outside of view port.
635         node->SetWidth(0.0);
636         node->SetHeight(0.0);
637         node->SetTop(0.0);
638         node->SetLeft(0.0);
639         return;
640     }
641     if (node->IsValidRect()) {
642         return; // Rect already clamp by viewport, no need to set again.
643     }
644     auto context = context_.Upgrade();
645     if (!context) {
646         return;
647     }
648     auto viewScale = context->GetViewScale();
649     if (NearZero(viewScale)) {
650         EventReport::SendRenderException(RenderExcepType::VIEW_SCALE_ERR);
651         return;
652     }
653 #if !defined(PREVIEW)
654     Size size = GetPaintSize() * viewScale;
655     Offset globalOffset = (GetGlobalOffsetExternal() + margin_.GetOffset()) * viewScale;
656     node->SetMarginSize(margin_.GetLayoutSize() * viewScale);
657     node->SetWidth(size.Width());
658     node->SetHeight(size.Height());
659     node->SetLeft(globalOffset.GetX());
660     node->SetTop(globalOffset.GetY());
661 #else
662     Size size = paintSize_;
663     Offset globalOffset = GetGlobalOffset();
664     globalOffset.SetX(globalOffset.GetX() + margin_.LeftPx());
665     globalOffset.SetY(globalOffset.GetY() + margin_.TopPx());
666     if (node->IsAnimationNode()) {
667         CalculateScale(node, globalOffset, size);
668         CalculateRotate(node, globalOffset, size);
669         CalculateTranslate(node, globalOffset, size);
670     }
671     size = size * viewScale;
672     globalOffset = globalOffset * viewScale;
673     node->SetWidth(size.Width());
674     node->SetHeight(size.Height());
675     node->SetLeft(globalOffset.GetX());
676     node->SetTop(globalOffset.GetY());
677 #endif
678 }
679 
GetGlobalOffsetExternal() const680 Offset RenderBox::GetGlobalOffsetExternal() const
681 {
682     auto renderNode = GetParent().Upgrade();
683     auto offset = renderNode ? GetPosition() + renderNode->GetGlobalOffsetExternal() : GetPosition();
684     offset += alignOffset_;
685     return offset;
686 }
687 
688 #if defined(PREVIEW)
CalculateScale(RefPtr<AccessibilityNode> node,Offset & globalOffset,Size & size)689 void RenderBox::CalculateScale(RefPtr<AccessibilityNode> node, Offset& globalOffset, Size& size)
690 {
691     double scaleFactor = node->GetScale();
692     Offset scaleCenter = node->GetScaleCenter();
693     if (!NearEqual(scaleFactor, 1.0)) {
694         if (NearEqual(scaleFactor, 0.0)) {
695             scaleFactor = 0.01;
696         }
697         // parent and children are scaled by the center point of parent.
698         auto currentOffset = globalOffset;
699         auto currentSize = size;
700         auto boxCenter =
701             Offset(currentOffset.GetX() + currentSize.Width() / 2.0, currentOffset.GetY() + currentSize.Height() / 2.0);
702         if (boxCenter == scaleCenter) {
703             globalOffset = Offset(currentSize.Width() * (1 - scaleFactor) / 2.0 + currentOffset.GetX(),
704                 currentSize.Height() * (1 - scaleFactor) / 2.0 + currentOffset.GetY());
705         } else {
706             auto center = scaleCenter;
707             globalOffset = Offset(scaleFactor * currentOffset.GetX() + (1 - scaleFactor) * center.GetX(),
708                 scaleFactor * currentOffset.GetY() + (1 - scaleFactor) * center.GetY());
709         }
710         size = size * scaleFactor;
711     }
712 }
713 
CalculateRotate(RefPtr<AccessibilityNode> node,Offset & globalOffset,Size & size)714 void RenderBox::CalculateRotate(RefPtr<AccessibilityNode> node, Offset& globalOffset, Size& size)
715 {
716     double angle = node->GetRotateAngle();
717     if (!NearEqual(angle, 0.0)) {
718         Point leftTop;
719         Point rightTop;
720         Point leftBottom;
721         Point rightBottom;
722         Point center = Point(node->GetScaleCenter().GetX(), node->GetScaleCenter().GetY());
723         leftTop.SetX(globalOffset.GetX());
724         leftTop.SetY(globalOffset.GetY());
725 
726         rightTop.SetX(globalOffset.GetX() + size.Width());
727         rightTop.SetY(globalOffset.GetY());
728 
729         leftBottom.SetX(globalOffset.GetX());
730         leftBottom.SetY(globalOffset.GetY() + size.Height());
731 
732         rightBottom.SetX(globalOffset.GetX() + size.Width());
733         rightBottom.SetY(globalOffset.GetY() + size.Height());
734         const double pi = std::acos(-1);
735         double RotateAngle = angle * pi / 180;
736 
737         leftTop.Rotate(center, RotateAngle);
738         rightTop.Rotate(center, RotateAngle);
739         leftBottom.Rotate(center, RotateAngle);
740         rightBottom.Rotate(center, RotateAngle);
741 
742         double min_X = std::min({ leftTop.GetX(), rightTop.GetX(), leftBottom.GetX(), rightBottom.GetX() });
743         double max_X = std::max({ leftTop.GetX(), rightTop.GetX(), leftBottom.GetX(), rightBottom.GetX() });
744         double min_Y = std::min({ leftTop.GetY(), rightTop.GetY(), leftBottom.GetY(), rightBottom.GetY() });
745         double max_Y = std::max({ leftTop.GetY(), rightTop.GetY(), leftBottom.GetY(), rightBottom.GetY() });
746         globalOffset.SetX(min_X);
747         globalOffset.SetY(min_Y);
748         size.SetWidth(max_X - min_X);
749         size.SetHeight(max_Y - min_Y);
750     }
751 }
752 
CalculateTranslate(RefPtr<AccessibilityNode> node,Offset & globalOffset,Size & size)753 void RenderBox::CalculateTranslate(RefPtr<AccessibilityNode> node, Offset& globalOffset, Size& size)
754 {
755     // calculate translate
756     Offset translateOffset = node->GetTranslateOffset();
757     globalOffset = globalOffset + translateOffset;
758 }
759 #endif
760 
SetBackgroundPosition(const BackgroundImagePosition & position)761 void RenderBox::SetBackgroundPosition(const BackgroundImagePosition& position)
762 {
763     if (backDecoration_ == nullptr) {
764         backDecoration_ = AceType::MakeRefPtr<Decoration>();
765     }
766     RefPtr<BackgroundImage> backgroundImage = backDecoration_->GetImage();
767     if (!backgroundImage) {
768         // Suppress error logs when do animation.
769         return;
770     }
771     if (backgroundImage->GetImagePosition() == position) {
772         return;
773     }
774     backgroundImage->SetImagePosition(position);
775     if (renderImage_) {
776         renderImage_->SetBgImagePosition(backgroundImage->GetImagePosition());
777     }
778     MarkNeedLayout();
779 }
780 
ClearRenderObject()781 void RenderBox::ClearRenderObject()
782 {
783     RenderBoxBase::ClearRenderObject();
784     renderImage_ = nullptr;
785     backDecoration_ = nullptr;
786     frontDecoration_ = nullptr;
787     controllerEnter_ = nullptr;
788     controllerExit_ = nullptr;
789     colorAnimationEnter_ = nullptr;
790     colorAnimationExit_ = nullptr;
791     hoverAnimationType_ = HoverAnimationType::UNKNOWN;
792     hoverColor_ = Color::TRANSPARENT;
793     for (size_t i = 0; i < recognizers_.size(); i++) {
794         recognizers_[i] = nullptr;
795     }
796 
797     dragDropGesture_ = nullptr;
798     parallelRecognizer_ = nullptr;
799     preDragDropNode_  = nullptr;
800     initialDragDropNode_ = nullptr;
801     updateBuilder_ = nullptr;
802     onDragStart_ = nullptr;
803     onDragEnter_ = nullptr;
804     onDragMove_ = nullptr;
805     onDragLeave_ = nullptr;
806     onDrop_ = nullptr;
807     onClick_ = nullptr;
808     onLongPress_ = nullptr;
809 }
810 
GetBackgroundPosition() const811 BackgroundImagePosition RenderBox::GetBackgroundPosition() const
812 {
813     if (backDecoration_ == nullptr) {
814         return BackgroundImagePosition();
815     }
816     RefPtr<BackgroundImage> backgroundImage = backDecoration_->GetImage();
817     if (!backgroundImage) {
818         LOGE("get background position failed. no background image.");
819         return BackgroundImagePosition();
820     }
821     return backgroundImage->GetImagePosition();
822 }
823 
SetBackgroundSize(const BackgroundImageSize & size)824 void RenderBox::SetBackgroundSize(const BackgroundImageSize& size)
825 {
826     if (backDecoration_ == nullptr) {
827         backDecoration_ = AceType::MakeRefPtr<Decoration>();
828     }
829     RefPtr<BackgroundImage> backgroundImage = backDecoration_->GetImage();
830     if (!backgroundImage) {
831         // Suppress error logs when do animation.
832         LOGE("set background size failed. no background image.");
833         return;
834     }
835     if (backgroundImage->GetImageSize() == size) {
836         return;
837     }
838     backgroundImage->SetImageSize(size);
839     if (renderImage_) {
840         // x direction
841         renderImage_->SetBgImageSize(size.GetSizeTypeX(), size.GetSizeValueX(), true);
842         // y direction
843         renderImage_->SetBgImageSize(size.GetSizeTypeY(), size.GetSizeValueY(), false);
844     }
845     MarkNeedLayout();
846 }
847 
GetBackgroundSize() const848 BackgroundImageSize RenderBox::GetBackgroundSize() const
849 {
850     if (backDecoration_ == nullptr) {
851         return BackgroundImageSize();
852     }
853     RefPtr<BackgroundImage> backgroundImage = backDecoration_->GetImage();
854     if (!backgroundImage) {
855         LOGE("get background size failed. no background image.");
856         return BackgroundImageSize();
857     }
858     return backgroundImage->GetImageSize();
859 }
860 
OnMouseHoverEnterAnimation()861 void RenderBox::OnMouseHoverEnterAnimation()
862 {
863     // stop the exit animation being played.
864     ResetController(controllerExit_);
865     if (!controllerEnter_) {
866         controllerEnter_ = CREATE_ANIMATOR(context_);
867     }
868     colorAnimationEnter_ = AceType::MakeRefPtr<KeyframeAnimation<Color>>();
869     if (hoverAnimationType_ == HoverAnimationType::OPACITY) {
870         if (!backDecoration_) {
871             backDecoration_ = AceType::MakeRefPtr<Decoration>();
872         }
873         CreateColorAnimation(colorAnimationEnter_, hoverColor_, Color::FromRGBO(0, 0, 0, 0.05));
874         colorAnimationEnter_->SetCurve(Curves::FRICTION);
875     }
876     controllerEnter_->AddInterpolator(colorAnimationEnter_);
877     controllerEnter_->SetDuration(HOVER_ANIMATION_DURATION);
878     controllerEnter_->Play();
879     controllerEnter_->SetFillMode(FillMode::FORWARDS);
880 }
881 
OnMouseHoverExitAnimation()882 void RenderBox::OnMouseHoverExitAnimation()
883 {
884     // stop the enter animation being played.
885     ResetController(controllerEnter_);
886     if (!controllerExit_) {
887         controllerExit_ = CREATE_ANIMATOR(context_);
888     }
889     colorAnimationExit_ = AceType::MakeRefPtr<KeyframeAnimation<Color>>();
890     if (hoverAnimationType_ == HoverAnimationType::OPACITY) {
891         if (!backDecoration_) {
892             backDecoration_ = AceType::MakeRefPtr<Decoration>();
893         }
894         // The exit animation plays from the current background color.
895         CreateColorAnimation(colorAnimationExit_, hoverColor_, Color::FromRGBO(0, 0, 0, 0.0));
896         if (hoverColor_ == Color::FromRGBO(0, 0, 0, 0.05)) {
897             colorAnimationExit_->SetCurve(Curves::FRICTION);
898         } else {
899             colorAnimationExit_->SetCurve(Curves::FAST_OUT_SLOW_IN);
900         }
901     }
902     controllerExit_->AddInterpolator(colorAnimationExit_);
903     controllerExit_->SetDuration(HOVER_ANIMATION_DURATION);
904     controllerExit_->Play();
905     controllerExit_->SetFillMode(FillMode::FORWARDS);
906 }
907 
CreateFloatAnimation(RefPtr<KeyframeAnimation<float>> & floatAnimation,float beginValue,float endValue)908 void RenderBox::CreateFloatAnimation(RefPtr<KeyframeAnimation<float>>& floatAnimation, float beginValue, float endValue)
909 {
910     if (!floatAnimation) {
911         return;
912     }
913     auto keyframeBegin = AceType::MakeRefPtr<Keyframe<float>>(0.0, beginValue);
914     auto keyframeEnd = AceType::MakeRefPtr<Keyframe<float>>(1.0, endValue);
915     floatAnimation->AddKeyframe(keyframeBegin);
916     floatAnimation->AddKeyframe(keyframeEnd);
917     floatAnimation->AddListener([weakBox = AceType::WeakClaim(this)](float value) {
918         auto box = weakBox.Upgrade();
919         if (box) {
920             box->scale_ = value;
921             box->MarkNeedRender();
922         }
923     });
924 }
925 
CreateColorAnimation(RefPtr<KeyframeAnimation<Color>> & colorAnimation,const Color & beginValue,const Color & endValue)926 void RenderBox::CreateColorAnimation(
927     RefPtr<KeyframeAnimation<Color>>& colorAnimation, const Color& beginValue, const Color& endValue)
928 {
929     if (!colorAnimation) {
930         return;
931     }
932     auto keyframeBegin = AceType::MakeRefPtr<Keyframe<Color>>(0.0, beginValue);
933     auto keyframeEnd = AceType::MakeRefPtr<Keyframe<Color>>(1.0, endValue);
934     colorAnimation->AddKeyframe(keyframeBegin);
935     colorAnimation->AddKeyframe(keyframeEnd);
936     if (!backDecoration_) {
937         backDecoration_ = AceType::MakeRefPtr<Decoration>();
938     }
939     colorAnimation->AddListener([weakBox = AceType::WeakClaim(this)](const Color& value) {
940         auto box = weakBox.Upgrade();
941         if (!box) {
942             return;
943         }
944         box->hoverColor_ = value;
945         if (box->GetBackDecoration()) {
946             box->GetBackDecoration()->SetBackgroundColor(box->hoverColor_);
947             box->GetBackDecoration()->SetAnimationColor(box->hoverColor_);
948         }
949         box->MarkNeedRender();
950     });
951 }
952 
AnimateMouseHoverEnter()953 void RenderBox::AnimateMouseHoverEnter()
954 {
955     MouseHoverEnterTest();
956 }
957 
MouseHoverEnterTest()958 void RenderBox::MouseHoverEnterTest()
959 {
960     ResetController(controllerExit_);
961     if (!controllerEnter_) {
962         controllerEnter_ = CREATE_ANIMATOR(context_);
963     }
964     if (hoverAnimationType_ == HoverAnimationType::SCALE) {
965         if (!scaleAnimationEnter_) {
966             scaleAnimationEnter_ = AceType::MakeRefPtr<KeyframeAnimation<float>>();
967         }
968         CreateFloatAnimation(scaleAnimationEnter_, 1.0, 1.05);
969         controllerEnter_->ClearInterpolators();
970         controllerEnter_->AddInterpolator(scaleAnimationEnter_);
971         isHoveredScale_ = true;
972     } else if (hoverAnimationType_ == HoverAnimationType::BOARD) {
973         if (!backDecoration_) {
974             backDecoration_ = AceType::MakeRefPtr<Decoration>();
975         }
976         if (!colorAnimationEnter_) {
977             colorAnimationEnter_ = AceType::MakeRefPtr<KeyframeAnimation<Color>>();
978         }
979         CreateColorAnimation(colorAnimationEnter_, hoverColorBegin_, Color::FromRGBO(0, 0, 0, 0.05));
980         controllerEnter_->ClearInterpolators();
981         controllerEnter_->AddInterpolator(colorAnimationEnter_);
982         isHoveredBoard_ = true;
983     } else {
984         return;
985     }
986     controllerEnter_->SetDuration(HOVER_ANIMATION_DURATION);
987     controllerEnter_->SetFillMode(FillMode::FORWARDS);
988     controllerEnter_->Play();
989 }
990 
ResetController(RefPtr<Animator> & controller)991 void RenderBox::ResetController(RefPtr<Animator>& controller)
992 {
993     if (controller) {
994         if (!controller->IsStopped()) {
995             controller->Stop();
996         }
997         controller->ClearInterpolators();
998     }
999 }
1000 
AnimateMouseHoverExit()1001 void RenderBox::AnimateMouseHoverExit()
1002 {
1003     MouseHoverExitTest();
1004 }
1005 
MouseHoverExitTest()1006 void RenderBox::MouseHoverExitTest()
1007 {
1008     ResetController(controllerEnter_);
1009     if (!controllerExit_) {
1010         controllerExit_ = CREATE_ANIMATOR(context_);
1011     }
1012     if (hoverAnimationType_ == HoverAnimationType::SCALE) {
1013         scaleAnimationExit_ = AceType::MakeRefPtr<KeyframeAnimation<float>>();
1014         auto begin = scale_;
1015         CreateFloatAnimation(scaleAnimationExit_, begin, 1.0);
1016         controllerExit_->ClearInterpolators();
1017         controllerExit_->AddInterpolator(scaleAnimationExit_);
1018         isHoveredScale_ = false;
1019     } else if (hoverAnimationType_ == HoverAnimationType::BOARD) {
1020         if (!backDecoration_) {
1021             backDecoration_ = AceType::MakeRefPtr<Decoration>();
1022         }
1023         if (!colorAnimationExit_) {
1024             colorAnimationExit_ = AceType::MakeRefPtr<KeyframeAnimation<Color>>();
1025         }
1026         CreateColorAnimation(colorAnimationExit_, hoverColor_, hoverColorBegin_);
1027         controllerExit_->ClearInterpolators();
1028         controllerExit_->AddInterpolator(colorAnimationExit_);
1029         isHoveredBoard_ = false;
1030     } else {
1031         return;
1032     }
1033     controllerExit_->SetDuration(HOVER_ANIMATION_DURATION);
1034     controllerExit_->Play();
1035     controllerExit_->SetFillMode(FillMode::FORWARDS);
1036 }
1037 
HandleMouseHoverEvent(MouseState mouseState)1038 void RenderBox::HandleMouseHoverEvent(MouseState mouseState)
1039 {
1040     HoverInfo info = HoverInfo();
1041     std::string accessibilityEventType;
1042     if (mouseState == MouseState::HOVER) {
1043         accessibilityEventType = "mousehoverenter";
1044     } else {
1045         accessibilityEventType = "mousehoverexit";
1046     }
1047     SendAccessibilityEvent(accessibilityEventType);
1048 
1049     if (onHover_) {
1050         onHover_(mouseState == MouseState::HOVER, info);
1051     }
1052 }
1053 
StopMouseHoverAnimation()1054 void RenderBox::StopMouseHoverAnimation()
1055 {
1056     if (controllerExit_) {
1057         if (!controllerExit_->IsStopped()) {
1058             controllerExit_->Stop();
1059         }
1060         controllerExit_->ClearInterpolators();
1061     }
1062 }
1063 
HandleMouseEvent(const MouseEvent & event)1064 bool RenderBox::HandleMouseEvent(const MouseEvent& event)
1065 {
1066     if (!onMouse_) {
1067         return false;
1068     }
1069 
1070     MouseInfo info;
1071     info.SetButton(event.button);
1072     info.SetAction(event.action);
1073     info.SetGlobalLocation(event.GetOffset());
1074     info.SetLocalLocation(event.GetOffset() - Offset(GetCoordinatePoint().GetX(), GetCoordinatePoint().GetY()));
1075     info.SetScreenLocation(event.GetScreenOffset());
1076     info.SetTimeStamp(event.time);
1077     info.SetDeviceId(event.deviceId);
1078     info.SetSourceDevice(event.sourceType);
1079 #ifdef LINUX_PLATFORM
1080     LOGI("RenderBox::HandleMouseEvent: Do mouse callback with mouse event{ Global(%{public}f,%{public}f), "
1081          "Local(%{public}f,%{public}f)}, Button(%{public}d), Action(%{public}d), "
1082          "DeviceId(%{public}" PRId64 ", SourceType(%{public}d) }. Return: %{public}d",
1083         info.GetGlobalLocation().GetX(), info.GetGlobalLocation().GetY(), info.GetLocalLocation().GetX(),
1084         info.GetLocalLocation().GetY(), info.GetButton(), info.GetAction(),
1085         info.GetDeviceId(), info.GetSourceDevice(), info.IsStopPropagation());
1086 #else
1087     LOGI("RenderBox::HandleMouseEvent: Do mouse callback with mouse event{ Global(%{public}f,%{public}f), "
1088          "Local(%{public}f,%{public}f)}, Button(%{public}d), Action(%{public}d), Time(%{public}lld), "
1089          ", SourceType(%{public}d) }. Return: %{public}d",
1090         info.GetGlobalLocation().GetX(), info.GetGlobalLocation().GetY(), info.GetLocalLocation().GetX(),
1091         info.GetLocalLocation().GetY(), info.GetButton(), info.GetAction(),
1092         info.GetTimeStamp().time_since_epoch().count(), info.GetSourceDevice(), info.IsStopPropagation());
1093 #endif
1094     onMouse_(info);
1095     return info.IsStopPropagation();
1096 }
1097 
GetColorPropertySetterMap()1098 ColorPropertyAnimatable::SetterMap RenderBox::GetColorPropertySetterMap()
1099 {
1100     ColorPropertyAnimatable::SetterMap map;
1101     auto weak = AceType::WeakClaim(this);
1102     const RefPtr<RenderTextField> renderTextField = AceType::DynamicCast<RenderTextField>(GetFirstChild());
1103     if (renderTextField) {
1104         WeakPtr<RenderTextField> textWeak = renderTextField;
1105         map[PropertyAnimatableType::PROPERTY_BACK_DECORATION_COLOR] = [textWeak](Color value) {
1106             auto renderTextField = textWeak.Upgrade();
1107             if (!renderTextField) {
1108                 return;
1109             }
1110             renderTextField->SetColor(value);
1111         };
1112     } else {
1113         map[PropertyAnimatableType::PROPERTY_BACK_DECORATION_COLOR] = [weak](Color value) {
1114             auto box = weak.Upgrade();
1115             if (!box) {
1116                 return;
1117             }
1118             box->SetColor(value, true);
1119         };
1120     }
1121     map[PropertyAnimatableType::PROPERTY_FRONT_DECORATION_COLOR] = [weak](Color value) {
1122         auto box = weak.Upgrade();
1123         if (!box) {
1124             return;
1125         }
1126         box->SetColor(value, false);
1127     };
1128     return map;
1129 }
1130 
GetColorPropertyGetterMap()1131 ColorPropertyAnimatable::GetterMap RenderBox::GetColorPropertyGetterMap()
1132 {
1133     ColorPropertyAnimatable::GetterMap map;
1134     auto weak = AceType::WeakClaim(this);
1135     map[PropertyAnimatableType::PROPERTY_FRONT_DECORATION_COLOR] = [weak]() -> Color {
1136         auto box = weak.Upgrade();
1137         if (!box) {
1138             return Color();
1139         }
1140         auto frontDecoration = box->GetFrontDecoration();
1141         if (frontDecoration) {
1142             return frontDecoration->GetBackgroundColor();
1143         }
1144         return Color::TRANSPARENT;
1145     };
1146     const RefPtr<RenderTextField> renderTextField = AceType::DynamicCast<RenderTextField>(GetFirstChild());
1147     if (renderTextField) {
1148         WeakPtr<RenderTextField> textWeak = renderTextField;
1149         map[PropertyAnimatableType::PROPERTY_BACK_DECORATION_COLOR] = [textWeak]() -> Color {
1150             auto renderTextField = textWeak.Upgrade();
1151             if (!renderTextField) {
1152                 return Color();
1153             }
1154             return renderTextField->GetColor();
1155         };
1156     } else {
1157         map[PropertyAnimatableType::PROPERTY_BACK_DECORATION_COLOR] = [weak]() -> Color {
1158             auto box = weak.Upgrade();
1159             if (!box) {
1160                 return Color();
1161             }
1162             return box->GetColor();
1163         };
1164     }
1165     return map;
1166 }
1167 
SetShadow(const Shadow & value)1168 void RenderBox::SetShadow(const Shadow& value)
1169 {
1170     if (backDecoration_ == nullptr) {
1171         backDecoration_ = AceType::MakeRefPtr<Decoration>();
1172     }
1173 
1174     auto shadows = backDecoration_->GetShadows();
1175     Shadow shadow;
1176 
1177     if (!shadows.empty()) {
1178         shadow = shadows.front();
1179     }
1180 
1181     if (shadow != value) {
1182         backDecoration_->ClearAllShadow();
1183         backDecoration_->AddShadow(value);
1184         MarkNeedLayout();
1185     }
1186 }
1187 
GetShadow() const1188 Shadow RenderBox::GetShadow() const
1189 {
1190     if (backDecoration_ != nullptr) {
1191         const auto& shadows = backDecoration_->GetShadows();
1192         if (!shadows.empty()) {
1193             return shadows.front();
1194         }
1195     }
1196     return {};
1197 }
1198 
SetGrayScale(double scale)1199 void RenderBox::SetGrayScale(double scale)
1200 {
1201     if (frontDecoration_ == nullptr) {
1202         frontDecoration_ = AceType::MakeRefPtr<Decoration>();
1203     }
1204     double _scale = frontDecoration_->GetGrayScale().Value();
1205     if (!NearEqual(_scale, scale)) {
1206         frontDecoration_->SetGrayScale(Dimension(_scale));
1207         MarkNeedRender();
1208     }
1209 }
1210 
GetGrayScale(void) const1211 double RenderBox::GetGrayScale(void) const
1212 {
1213     if (frontDecoration_ != nullptr) {
1214         return frontDecoration_->GetGrayScale().Value();
1215     }
1216     return 0.0;
1217 }
1218 
SetBrightness(double ness)1219 void RenderBox::SetBrightness(double ness)
1220 {
1221     if (frontDecoration_ == nullptr) {
1222         frontDecoration_ = AceType::MakeRefPtr<Decoration>();
1223     }
1224     double brightness = frontDecoration_->GetBrightness().Value();
1225     if (!NearEqual(brightness, ness)) {
1226         frontDecoration_->SetBrightness(Dimension(brightness));
1227         MarkNeedRender();
1228     }
1229 }
1230 
GetBrightness(void) const1231 double RenderBox::GetBrightness(void) const
1232 {
1233     if (frontDecoration_ != nullptr) {
1234         return frontDecoration_->GetBrightness().Value();
1235     }
1236     return 0.0;
1237 }
1238 
SetContrast(double trast)1239 void RenderBox::SetContrast(double trast)
1240 {
1241     if (frontDecoration_ == nullptr) {
1242         frontDecoration_ = AceType::MakeRefPtr<Decoration>();
1243     }
1244     double contrast = frontDecoration_->GetContrast().Value();
1245     if (!NearEqual(contrast, trast)) {
1246         frontDecoration_->SetContrast(Dimension(contrast));
1247         MarkNeedRender();
1248     }
1249 }
1250 
GetContrast(void) const1251 double RenderBox::GetContrast(void) const
1252 {
1253     if (frontDecoration_ != nullptr) {
1254         return frontDecoration_->GetContrast().Value();
1255     }
1256     return 0.0;
1257 }
1258 
SetColorBlend(const Color & color)1259 void RenderBox::SetColorBlend(const Color& color)
1260 {
1261     if (frontDecoration_ == nullptr) {
1262         frontDecoration_ = AceType::MakeRefPtr<Decoration>();
1263     }
1264     if (!NearEqual(frontDecoration_->GetColorBlend().GetValue(), color.GetValue())) {
1265         frontDecoration_->SetColorBlend(color);
1266         MarkNeedRender();
1267     }
1268 }
1269 
GetColorBlend() const1270 Color RenderBox::GetColorBlend() const
1271 {
1272     if (frontDecoration_) {
1273         return frontDecoration_->GetColorBlend();
1274     }
1275     return {};
1276 }
1277 
SetSaturate(double rate)1278 void RenderBox::SetSaturate(double rate)
1279 {
1280     if (frontDecoration_ == nullptr) {
1281         frontDecoration_ = AceType::MakeRefPtr<Decoration>();
1282     }
1283     double saturate = frontDecoration_->GetSaturate().Value();
1284     if (!NearEqual(saturate, rate)) {
1285         frontDecoration_->SetSaturate(Dimension(saturate));
1286         MarkNeedRender();
1287     }
1288 }
1289 
GetSaturate(void) const1290 double RenderBox::GetSaturate(void) const
1291 {
1292     if (frontDecoration_ != nullptr) {
1293         return frontDecoration_->GetSaturate().Value();
1294     }
1295     return 0.0;
1296 }
1297 
SetSepia(double pia)1298 void RenderBox::SetSepia(double pia)
1299 {
1300     if (frontDecoration_ == nullptr) {
1301         frontDecoration_ = AceType::MakeRefPtr<Decoration>();
1302     }
1303     double pias = frontDecoration_->GetSepia().Value();
1304     if (!NearEqual(pias, pia)) {
1305         frontDecoration_->SetSepia(Dimension(pias));
1306         MarkNeedRender();
1307     }
1308 }
1309 
GetSepia(void) const1310 double RenderBox::GetSepia(void) const
1311 {
1312     if (frontDecoration_ != nullptr) {
1313         return frontDecoration_->GetSepia().Value();
1314     }
1315     return 0.0;
1316 }
1317 
SetInvert(double invert)1318 void RenderBox::SetInvert(double invert)
1319 {
1320     if (frontDecoration_ == nullptr) {
1321         frontDecoration_ = AceType::MakeRefPtr<Decoration>();
1322     }
1323     double inverts = frontDecoration_->GetInvert().Value();
1324     if (!NearEqual(inverts, invert)) {
1325         frontDecoration_->SetInvert(Dimension(inverts));
1326         MarkNeedRender();
1327     }
1328 }
1329 
GetInvert(void) const1330 double RenderBox::GetInvert(void) const
1331 {
1332     if (frontDecoration_ != nullptr) {
1333         return frontDecoration_->GetInvert().Value();
1334     }
1335     return 0.0;
1336 }
1337 
SetHueRotate(float deg)1338 void RenderBox::SetHueRotate(float deg)
1339 {
1340     if (frontDecoration_ == nullptr) {
1341         frontDecoration_ = AceType::MakeRefPtr<Decoration>();
1342     }
1343     float degs = frontDecoration_->GetHueRotate();
1344     if (!NearEqual(degs, deg)) {
1345         frontDecoration_->SetHueRotate(degs);
1346         MarkNeedRender();
1347     }
1348 }
1349 
GetHueRotate(void) const1350 float RenderBox::GetHueRotate(void) const
1351 {
1352     if (frontDecoration_ != nullptr) {
1353         return frontDecoration_->GetHueRotate();
1354     }
1355     return 0.0;
1356 }
1357 
SetBorderWidth(double width,const BorderEdgeHelper & helper)1358 void RenderBox::SetBorderWidth(double width, const BorderEdgeHelper& helper)
1359 {
1360     if (backDecoration_ == nullptr) {
1361         backDecoration_ = AceType::MakeRefPtr<Decoration>();
1362     }
1363     Border border = backDecoration_->GetBorder();
1364     if (helper.Set(width, &border)) {
1365         backDecoration_->SetBorder(border);
1366         MarkNeedLayout();
1367     }
1368 }
1369 
GetBorderWidth(const BorderEdgeHelper & helper) const1370 double RenderBox::GetBorderWidth(const BorderEdgeHelper& helper) const
1371 {
1372     if (backDecoration_ != nullptr) {
1373         return helper.Get(backDecoration_->GetBorder()).GetWidth().Value();
1374     }
1375     return 0.0;
1376 }
1377 
SetBorderColor(const Color & color,const BorderEdgeHelper & helper)1378 void RenderBox::SetBorderColor(const Color& color, const BorderEdgeHelper& helper)
1379 {
1380     if (backDecoration_ == nullptr) {
1381         backDecoration_ = AceType::MakeRefPtr<Decoration>();
1382     }
1383     Border border = backDecoration_->GetBorder();
1384     if (helper.Set(color, &border)) {
1385         backDecoration_->SetBorder(border);
1386         MarkNeedLayout();
1387     }
1388 }
1389 
GetBorderColor(const BorderEdgeHelper & helper) const1390 Color RenderBox::GetBorderColor(const BorderEdgeHelper& helper) const
1391 {
1392     if (backDecoration_) {
1393         return helper.Get(backDecoration_->GetBorder()).GetColor();
1394     }
1395     return {};
1396 }
1397 
SetBorderStyle(BorderStyle borderStyle,const BorderEdgeHelper & helper)1398 void RenderBox::SetBorderStyle(BorderStyle borderStyle, const BorderEdgeHelper& helper)
1399 {
1400     if (backDecoration_ == nullptr) {
1401         backDecoration_ = AceType::MakeRefPtr<Decoration>();
1402     }
1403     Border border = backDecoration_->GetBorder();
1404     if (helper.Set(borderStyle, &border)) {
1405         backDecoration_->SetBorder(border);
1406         MarkNeedLayout();
1407     }
1408 }
1409 
GetBorderStyle(const BorderEdgeHelper & helper) const1410 BorderStyle RenderBox::GetBorderStyle(const BorderEdgeHelper& helper) const
1411 {
1412     if (backDecoration_) {
1413         return helper.Get(backDecoration_->GetBorder()).GetBorderStyle();
1414     }
1415     return BorderStyle::NONE;
1416 }
1417 
SetBorderRadius(double radius,const BorderRadiusHelper & helper)1418 void RenderBox::SetBorderRadius(double radius, const BorderRadiusHelper& helper)
1419 {
1420     if (backDecoration_ == nullptr) {
1421         backDecoration_ = AceType::MakeRefPtr<Decoration>();
1422     }
1423     Border border = backDecoration_->GetBorder();
1424     if (helper.Set(radius, &border)) {
1425         backDecoration_->SetBorder(border);
1426         MarkNeedLayout();
1427     }
1428 }
1429 
GetBorderRadius(const BorderRadiusHelper & helper) const1430 double RenderBox::GetBorderRadius(const BorderRadiusHelper& helper) const
1431 {
1432     if (backDecoration_) {
1433         return helper.Get(backDecoration_->GetBorder());
1434     }
1435     return 0.0;
1436 }
1437 
SetBlurRadius(const AnimatableDimension & radius)1438 void RenderBox::SetBlurRadius(const AnimatableDimension& radius)
1439 {
1440     if (frontDecoration_ == nullptr) {
1441         frontDecoration_ = AceType::MakeRefPtr<Decoration>();
1442     }
1443     if (!NearEqual(frontDecoration_->GetBlurRadius().Value(), radius.Value())) {
1444         frontDecoration_->SetBlurRadius(radius);
1445         MarkNeedRender();
1446     }
1447 }
1448 
GetBlurRadius() const1449 AnimatableDimension RenderBox::GetBlurRadius() const
1450 {
1451     if (frontDecoration_) {
1452         return frontDecoration_->GetBlurRadius();
1453     }
1454     return AnimatableDimension(0.0, DimensionUnit::PX);
1455 }
1456 
SetBackdropRadius(const AnimatableDimension & radius)1457 void RenderBox::SetBackdropRadius(const AnimatableDimension& radius)
1458 {
1459     if (backDecoration_ == nullptr) {
1460         backDecoration_ = AceType::MakeRefPtr<Decoration>();
1461     }
1462     if (!NearEqual(backDecoration_->GetBlurRadius().Value(), radius.Value())) {
1463         backDecoration_->SetBlurRadius(radius);
1464         MarkNeedRender();
1465     }
1466 }
1467 
GetBackdropRadius() const1468 AnimatableDimension RenderBox::GetBackdropRadius() const
1469 {
1470     if (backDecoration_) {
1471         return backDecoration_->GetBlurRadius();
1472     }
1473     return AnimatableDimension(0.0, DimensionUnit::PX);
1474 }
1475 
SetWindowBlurProgress(double progress)1476 void RenderBox::SetWindowBlurProgress(double progress)
1477 {
1478     if (backDecoration_ == nullptr) {
1479         backDecoration_ = AceType::MakeRefPtr<Decoration>();
1480     }
1481     if (!NearEqual(backDecoration_->GetWindowBlurProgress(), progress)) {
1482         backDecoration_->SetWindowBlurProgress(progress);
1483         MarkNeedRender();
1484     }
1485 }
1486 
GetWindowBlurProgress() const1487 double RenderBox::GetWindowBlurProgress() const
1488 {
1489     if (backDecoration_) {
1490         return backDecoration_->GetWindowBlurProgress();
1491     }
1492     return 0.0;
1493 }
1494 
AddRecognizerToResult(const Offset & coordinateOffset,const TouchRestrict & touchRestrict,TouchTestResult & result)1495 void RenderBox::AddRecognizerToResult(
1496     const Offset& coordinateOffset, const TouchRestrict& touchRestrict, TouchTestResult& result)
1497 {
1498     if (!ExistGestureRecognizer()) {
1499         return;
1500     }
1501 
1502     bool ignoreInternal = false;
1503     for (int i = MAX_GESTURE_SIZE - 1; i >= 0; i--) {
1504         if (recognizers_[i]) {
1505             ignoreInternal = recognizers_[i]->GetPriorityMask() == GestureMask::IgnoreInternal;
1506             if (ignoreInternal) {
1507                 break;
1508             }
1509         }
1510     }
1511 
1512     if (ignoreInternal) {
1513         auto iter = result.begin();
1514         while (iter != result.end()) {
1515             auto recognizer = AceType::DynamicCast<GestureRecognizer>(*iter);
1516             if (!recognizer) {
1517                 iter++;
1518                 continue;
1519             }
1520 
1521             if (!recognizer->GetIsExternalGesture()) {
1522                 iter++;
1523                 continue;
1524             }
1525             iter = result.erase(iter);
1526         }
1527     }
1528 
1529     for (int i = MAX_GESTURE_SIZE - 1; i >= 0; i--) {
1530         if (recognizers_[i]) {
1531             recognizers_[i]->SetCoordinateOffset(coordinateOffset);
1532             result.emplace_back(recognizers_[i]);
1533         }
1534     }
1535 }
1536 
OnTouchTestHit(const Offset & coordinateOffset,const TouchRestrict & touchRestrict,TouchTestResult & result)1537 void RenderBox::OnTouchTestHit(
1538     const Offset& coordinateOffset, const TouchRestrict& touchRestrict, TouchTestResult& result)
1539 {
1540     AddRecognizerToResult(coordinateOffset, touchRestrict, result);
1541     if (touchRecognizer_) {
1542         touchRecognizer_->SetCoordinateOffset(coordinateOffset);
1543         result.emplace_back(touchRecognizer_);
1544         MarkIsNotSiblingAddRecognizerToResult(false);
1545     }
1546     if (onClick_) {
1547         onClick_->SetCoordinateOffset(coordinateOffset);
1548         result.emplace_back(onClick_);
1549         MarkIsNotSiblingAddRecognizerToResult(true);
1550     }
1551     if (onLongPress_ && dragDropGesture_) {
1552         std::vector<RefPtr<GestureRecognizer>> recognizers { onLongPress_, dragDropGesture_ };
1553         parallelRecognizer_ = AceType::MakeRefPtr<OHOS::Ace::ParallelRecognizer>(recognizers);
1554         parallelRecognizer_->SetCoordinateOffset(coordinateOffset);
1555         result.emplace_back(parallelRecognizer_);
1556         MarkIsNotSiblingAddRecognizerToResult(true);
1557         return;
1558     }
1559     if (onLongPress_) {
1560         onLongPress_->SetCoordinateOffset(coordinateOffset);
1561         result.emplace_back(onLongPress_);
1562         MarkIsNotSiblingAddRecognizerToResult(true);
1563     }
1564     if (dragDropGesture_) {
1565         dragDropGesture_->SetCoordinateOffset(coordinateOffset);
1566         result.emplace_back(dragDropGesture_);
1567         MarkIsNotSiblingAddRecognizerToResult(true);
1568     }
1569 }
1570 
UpdateGestureRecognizer(const std::array<RefPtr<Gesture>,MAX_GESTURE_SIZE> & gestures)1571 void RenderBox::UpdateGestureRecognizer(const std::array<RefPtr<Gesture>, MAX_GESTURE_SIZE>& gestures)
1572 {
1573     // Considering 4 cases:
1574     // 1. new gesture == null && old recognizer == null  -->  do nothing
1575     // 2. new gesture != null && old recognizer == null  -->  create new recognizer configured with new gesture
1576     // 3. new gesture == null && old recognizer != null  -->  remove old recognizer
1577     // 4. new gesture != null && old recognizer != null  -->  update old recognizer with new configuration if
1578     // possible(determined by[GestureRecognizer::ReconcileFrom]), or remove the old recognizer and create new
1579     // one configured with new gesture.
1580     for (size_t i = 0; i < gestures.size(); i++) {
1581         if (!gestures[i]) {
1582             recognizers_[i] = nullptr;
1583             continue;
1584         }
1585         auto recognizer = gestures[i]->CreateRecognizer(context_);
1586         if (recognizer) {
1587             recognizer->SetIsExternalGesture(true);
1588             if (!recognizers_[i] || !recognizers_[i]->ReconcileFrom(recognizer)) {
1589                 recognizers_[i] = recognizer;
1590             }
1591         }
1592     }
1593 }
1594 
ExistGestureRecognizer()1595 bool RenderBox::ExistGestureRecognizer()
1596 {
1597     for (size_t i = 0; i < recognizers_.size(); i++) {
1598         if (recognizers_[i]) {
1599             return true;
1600         }
1601     }
1602 
1603     return false;
1604 }
1605 
HandleRemoteMessage(const ClickInfo & clickInfo)1606 void RenderBox::HandleRemoteMessage(const ClickInfo& clickInfo)
1607 {
1608     if (remoteMessageEvent_) {
1609         remoteMessageEvent_(std::make_shared<ClickInfo>(clickInfo));
1610     }
1611 }
1612 
OnStatusStyleChanged(const VisualState state)1613 void RenderBox::OnStatusStyleChanged(const VisualState state)
1614 {
1615     RenderBoxBase::OnStatusStyleChanged(state);
1616 
1617     if (stateAttributeList_ == nullptr) {
1618         return;
1619     }
1620 
1621     bool updated = false;
1622     for (auto& attribute : stateAttributeList_->GetAttributesForState(state)) {
1623         updated = true;
1624         switch (attribute->id_) {
1625             case BoxStateAttribute::COLOR: {
1626                 auto colorState =
1627                     AceType::DynamicCast<StateAttributeValue<BoxStateAttribute, AnimatableColor>>(attribute);
1628                 GetBackDecoration()->SetBackgroundColor(colorState->value_);
1629                 break;
1630             }
1631 
1632             case BoxStateAttribute::BORDER_COLOR: {
1633                 auto colorState =
1634                     AceType::DynamicCast<StateAttributeValue<BoxStateAttribute, AnimatableColor>>(attribute);
1635                 BoxComponentHelper::SetBorderColor(GetBackDecoration(), colorState->value_);
1636                 break;
1637             }
1638 
1639             case BoxStateAttribute::BORDER_RADIUS: {
1640                 auto radiusState =
1641                     AceType::DynamicCast<StateAttributeValue<BoxStateAttribute, AnimatableDimension>>(attribute);
1642                 BoxComponentHelper::SetBorderRadius(GetBackDecoration(), radiusState->value_);
1643                 break;
1644             }
1645 
1646             case BoxStateAttribute::BORDER_STYLE: {
1647                 auto attributeStateValue =
1648                     AceType::DynamicCast<StateAttributeValue<BoxStateAttribute, BorderStyle>>(attribute);
1649                 BoxComponentHelper::SetBorderStyle(GetBackDecoration(), attributeStateValue->value_);
1650                 break;
1651             }
1652 
1653             case BoxStateAttribute::BORDER_WIDTH: {
1654                 auto widthState =
1655                     AceType::DynamicCast<StateAttributeValue<BoxStateAttribute, AnimatableDimension>>(attribute);
1656                 BoxComponentHelper::SetBorderWidth(GetBackDecoration(), widthState->value_);
1657                 break;
1658             }
1659 
1660             case BoxStateAttribute::HEIGHT: {
1661                 auto valueState = AceType::DynamicCast<StateAttributeValue<BoxStateAttribute, Dimension>>(attribute);
1662                 height_ = valueState->value_;
1663                 break;
1664             }
1665 
1666             case BoxStateAttribute::WIDTH: {
1667                 auto valueState =
1668                     AceType::DynamicCast<StateAttributeValue<BoxStateAttribute, AnimatableDimension>>(attribute);
1669                 width_ = valueState->value_;
1670                 break;
1671             }
1672 
1673             case BoxStateAttribute::ASPECT_RATIO: {
1674                 auto valueState =
1675                     AceType::DynamicCast<StateAttributeValue<BoxStateAttribute, AnimatableDimension>>(attribute);
1676                 SetAspectRatio(valueState->value_);
1677                 break;
1678             }
1679 
1680             case BoxStateAttribute::BORDER: {
1681                 // We replace support for border object with updates to border components:
1682                 // color, style, width, radius
1683                 // The reason - developer does not have to provide all border properties
1684                 // when border is set.
1685                 // See JSViewAbstract::JsBorder for details
1686                 break;
1687             }
1688 
1689             case BoxStateAttribute::GRADIENT: {
1690                 auto gradientState = AceType::DynamicCast<StateAttributeValue<BoxStateAttribute, Gradient>>(attribute);
1691                 GetBackDecoration()->SetGradient(gradientState->value_);
1692                 break;
1693             }
1694             default:
1695                 break;
1696         }
1697     }
1698     if (updated) {
1699         MarkNeedLayout();
1700     }
1701 };
1702 
1703 } // namespace OHOS::Ace
1704