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