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