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