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