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_ = CREATE_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_ = CREATE_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_ = CREATE_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_ = CREATE_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 HoverInfo info = HoverInfo();
1072 std::string accessibilityEventType;
1073 if (mouseState == MouseState::HOVER) {
1074 accessibilityEventType = "mousehoverenter";
1075 } else {
1076 accessibilityEventType = "mousehoverexit";
1077 }
1078 SendAccessibilityEvent(accessibilityEventType);
1079
1080 if (onHover_) {
1081 onHover_(mouseState == MouseState::HOVER, info);
1082 }
1083 }
1084
StopMouseHoverAnimation()1085 void RenderBox::StopMouseHoverAnimation()
1086 {
1087 if (controllerExit_) {
1088 if (!controllerExit_->IsStopped()) {
1089 controllerExit_->Stop();
1090 }
1091 controllerExit_->ClearInterpolators();
1092 }
1093 }
1094
HandleMouseEvent(const MouseEvent & event)1095 bool RenderBox::HandleMouseEvent(const MouseEvent& event)
1096 {
1097 if (!onMouse_) {
1098 return false;
1099 }
1100
1101 MouseInfo info;
1102 info.SetButton(event.button);
1103 info.SetAction(event.action);
1104 info.SetGlobalLocation(event.GetOffset());
1105 info.SetLocalLocation(event.GetOffset() - Offset(GetCoordinatePoint().GetX(), GetCoordinatePoint().GetY()));
1106 info.SetScreenLocation(event.GetScreenOffset());
1107 info.SetTimeStamp(event.time);
1108 info.SetDeviceId(event.deviceId);
1109 info.SetSourceDevice(event.sourceType);
1110 #ifdef LINUX_PLATFORM
1111 LOGI("RenderBox::HandleMouseEvent: Do mouse callback with mouse event{ Global(%{public}f,%{public}f), "
1112 "Local(%{public}f,%{public}f)}, Button(%{public}d), Action(%{public}d), "
1113 "DeviceId(%{public}" PRId64 ", SourceType(%{public}d) }. Return: %{public}d",
1114 info.GetGlobalLocation().GetX(), info.GetGlobalLocation().GetY(), info.GetLocalLocation().GetX(),
1115 info.GetLocalLocation().GetY(), info.GetButton(), info.GetAction(),
1116 info.GetDeviceId(), info.GetSourceDevice(), info.IsStopPropagation());
1117 #else
1118 LOGI("RenderBox::HandleMouseEvent: Do mouse callback with mouse event{ Global(%{public}f,%{public}f), "
1119 "Local(%{public}f,%{public}f)}, Button(%{public}d), Action(%{public}d), Time(%{public}lld), "
1120 "DeviceId(%{public}" PRId64 ", SourceType(%{public}d) }. Return: %{public}d",
1121 info.GetGlobalLocation().GetX(), info.GetGlobalLocation().GetY(), info.GetLocalLocation().GetX(),
1122 info.GetLocalLocation().GetY(), info.GetButton(), info.GetAction(),
1123 info.GetTimeStamp().time_since_epoch().count(), info.GetDeviceId(), info.GetSourceDevice(),
1124 info.IsStopPropagation());
1125 #endif
1126 onMouse_(info);
1127 return info.IsStopPropagation();
1128 }
1129
GetColorPropertySetterMap()1130 ColorPropertyAnimatable::SetterMap RenderBox::GetColorPropertySetterMap()
1131 {
1132 ColorPropertyAnimatable::SetterMap map;
1133 auto weak = AceType::WeakClaim(this);
1134 const RefPtr<RenderTextField> renderTextField = AceType::DynamicCast<RenderTextField>(GetFirstChild());
1135 if (renderTextField) {
1136 WeakPtr<RenderTextField> textWeak = renderTextField;
1137 map[PropertyAnimatableType::PROPERTY_BACK_DECORATION_COLOR] = [textWeak](Color value) {
1138 auto renderTextField = textWeak.Upgrade();
1139 if (!renderTextField) {
1140 return;
1141 }
1142 renderTextField->SetColor(value);
1143 };
1144 } else {
1145 map[PropertyAnimatableType::PROPERTY_BACK_DECORATION_COLOR] = [weak](Color value) {
1146 auto box = weak.Upgrade();
1147 if (!box) {
1148 return;
1149 }
1150 box->SetColor(value, true);
1151 };
1152 }
1153 map[PropertyAnimatableType::PROPERTY_FRONT_DECORATION_COLOR] = [weak](Color value) {
1154 auto box = weak.Upgrade();
1155 if (!box) {
1156 return;
1157 }
1158 box->SetColor(value, false);
1159 };
1160 return map;
1161 }
1162
GetColorPropertyGetterMap()1163 ColorPropertyAnimatable::GetterMap RenderBox::GetColorPropertyGetterMap()
1164 {
1165 ColorPropertyAnimatable::GetterMap map;
1166 auto weak = AceType::WeakClaim(this);
1167 map[PropertyAnimatableType::PROPERTY_FRONT_DECORATION_COLOR] = [weak]() -> Color {
1168 auto box = weak.Upgrade();
1169 if (!box) {
1170 return Color();
1171 }
1172 auto frontDecoration = box->GetFrontDecoration();
1173 if (frontDecoration) {
1174 return frontDecoration->GetBackgroundColor();
1175 }
1176 return Color::TRANSPARENT;
1177 };
1178 const RefPtr<RenderTextField> renderTextField = AceType::DynamicCast<RenderTextField>(GetFirstChild());
1179 if (renderTextField) {
1180 WeakPtr<RenderTextField> textWeak = renderTextField;
1181 map[PropertyAnimatableType::PROPERTY_BACK_DECORATION_COLOR] = [textWeak]() -> Color {
1182 auto renderTextField = textWeak.Upgrade();
1183 if (!renderTextField) {
1184 return Color();
1185 }
1186 return renderTextField->GetColor();
1187 };
1188 } else {
1189 map[PropertyAnimatableType::PROPERTY_BACK_DECORATION_COLOR] = [weak]() -> Color {
1190 auto box = weak.Upgrade();
1191 if (!box) {
1192 return Color();
1193 }
1194 return box->GetColor();
1195 };
1196 }
1197 return map;
1198 }
1199
SetShadow(const Shadow & value)1200 void RenderBox::SetShadow(const Shadow& value)
1201 {
1202 if (backDecoration_ == nullptr) {
1203 backDecoration_ = AceType::MakeRefPtr<Decoration>();
1204 }
1205
1206 auto shadows = backDecoration_->GetShadows();
1207 Shadow shadow;
1208
1209 if (!shadows.empty()) {
1210 shadow = shadows.front();
1211 }
1212
1213 if (shadow != value) {
1214 backDecoration_->ClearAllShadow();
1215 backDecoration_->AddShadow(value);
1216 MarkNeedLayout();
1217 }
1218 }
1219
GetShadow() const1220 Shadow RenderBox::GetShadow() const
1221 {
1222 if (backDecoration_ != nullptr) {
1223 const auto& shadows = backDecoration_->GetShadows();
1224 if (!shadows.empty()) {
1225 return shadows.front();
1226 }
1227 }
1228 return {};
1229 }
1230
SetGrayScale(double scale)1231 void RenderBox::SetGrayScale(double scale)
1232 {
1233 if (frontDecoration_ == nullptr) {
1234 frontDecoration_ = AceType::MakeRefPtr<Decoration>();
1235 }
1236
1237 double _scale = frontDecoration_->GetGrayScale().Value();
1238
1239 if (!NearEqual(_scale, scale)) {
1240 frontDecoration_->SetGrayScale(Dimension(_scale));
1241 MarkNeedRender();
1242 }
1243 }
1244
GetGrayScale(void) const1245 double RenderBox::GetGrayScale(void) const
1246 {
1247 if (frontDecoration_ != nullptr) {
1248 return frontDecoration_->GetGrayScale().Value();
1249 }
1250
1251 return 0.0;
1252 }
1253
SetBrightness(double ness)1254 void RenderBox::SetBrightness(double ness)
1255 {
1256 if (frontDecoration_ == nullptr) {
1257 frontDecoration_ = AceType::MakeRefPtr<Decoration>();
1258 }
1259
1260 double brightness = frontDecoration_->GetBrightness().Value();
1261
1262 if (!NearEqual(brightness, ness)) {
1263 frontDecoration_->SetBrightness(Dimension(brightness));
1264 MarkNeedRender();
1265 }
1266 }
1267
GetBrightness(void) const1268 double RenderBox::GetBrightness(void) const
1269 {
1270 if (frontDecoration_ != nullptr) {
1271 return frontDecoration_->GetBrightness().Value();
1272 }
1273 return 0.0;
1274 }
1275
SetContrast(double trast)1276 void RenderBox::SetContrast(double trast)
1277 {
1278 if (frontDecoration_ == nullptr) {
1279 frontDecoration_ = AceType::MakeRefPtr<Decoration>();
1280 }
1281 double contrast = frontDecoration_->GetContrast().Value();
1282 if (!NearEqual(contrast, trast)) {
1283 frontDecoration_->SetContrast(Dimension(contrast));
1284 MarkNeedRender();
1285 }
1286 }
1287
GetContrast(void) const1288 double RenderBox::GetContrast(void) const
1289 {
1290 if (frontDecoration_ != nullptr) {
1291 return frontDecoration_->GetContrast().Value();
1292 }
1293 return 0.0;
1294 }
1295
SetColorBlend(const Color & color)1296 void RenderBox::SetColorBlend(const Color& color)
1297 {
1298 if (frontDecoration_ == nullptr) {
1299 frontDecoration_ = AceType::MakeRefPtr<Decoration>();
1300 }
1301 if (!NearEqual(frontDecoration_->GetColorBlend().GetValue(), color.GetValue())) {
1302 frontDecoration_->SetColorBlend(color);
1303 MarkNeedRender();
1304 }
1305 }
1306
GetColorBlend() const1307 Color RenderBox::GetColorBlend() const
1308 {
1309 if (frontDecoration_) {
1310 return frontDecoration_->GetColorBlend();
1311 }
1312 return {};
1313 }
1314
SetSaturate(double rate)1315 void RenderBox::SetSaturate(double rate)
1316 {
1317 if (frontDecoration_ == nullptr) {
1318 frontDecoration_ = AceType::MakeRefPtr<Decoration>();
1319 }
1320 double saturate = frontDecoration_->GetSaturate().Value();
1321 if (!NearEqual(saturate, rate)) {
1322 frontDecoration_->SetSaturate(Dimension(saturate));
1323 MarkNeedRender();
1324 }
1325 }
1326
GetSaturate(void) const1327 double RenderBox::GetSaturate(void) const
1328 {
1329 if (frontDecoration_ != nullptr) {
1330 return frontDecoration_->GetSaturate().Value();
1331 }
1332 return 0.0;
1333 }
1334
SetSepia(double pia)1335 void RenderBox::SetSepia(double pia)
1336 {
1337 if (frontDecoration_ == nullptr) {
1338 frontDecoration_ = AceType::MakeRefPtr<Decoration>();
1339 }
1340 double pias = frontDecoration_->GetSepia().Value();
1341 if (!NearEqual(pias, pia)) {
1342 frontDecoration_->SetSepia(Dimension(pias));
1343 MarkNeedRender();
1344 }
1345 }
1346
GetSepia(void) const1347 double RenderBox::GetSepia(void) const
1348 {
1349 if (frontDecoration_ != nullptr) {
1350 return frontDecoration_->GetSepia().Value();
1351 }
1352 return 0.0;
1353 }
1354
SetInvert(double invert)1355 void RenderBox::SetInvert(double invert)
1356 {
1357 if (frontDecoration_ == nullptr) {
1358 frontDecoration_ = AceType::MakeRefPtr<Decoration>();
1359 }
1360 double inverts = frontDecoration_->GetInvert().Value();
1361 if (!NearEqual(inverts, invert)) {
1362 frontDecoration_->SetInvert(Dimension(inverts));
1363 MarkNeedRender();
1364 }
1365 }
1366
GetInvert(void) const1367 double RenderBox::GetInvert(void) const
1368 {
1369 if (frontDecoration_ != nullptr) {
1370 return frontDecoration_->GetInvert().Value();
1371 }
1372 return 0.0;
1373 }
1374
SetHueRotate(float deg)1375 void RenderBox::SetHueRotate(float deg)
1376 {
1377 if (frontDecoration_ == nullptr) {
1378 frontDecoration_ = AceType::MakeRefPtr<Decoration>();
1379 }
1380 float degs = frontDecoration_->GetHueRotate();
1381 if (!NearEqual(degs, deg)) {
1382 frontDecoration_->SetHueRotate(degs);
1383 MarkNeedRender();
1384 }
1385 }
1386
GetHueRotate(void) const1387 float RenderBox::GetHueRotate(void) const
1388 {
1389 if (frontDecoration_ != nullptr) {
1390 return frontDecoration_->GetHueRotate();
1391 }
1392 return 0.0;
1393 }
1394
SetBorderWidth(double width,const BorderEdgeHelper & helper)1395 void RenderBox::SetBorderWidth(double width, const BorderEdgeHelper& helper)
1396 {
1397 if (backDecoration_ == nullptr) {
1398 backDecoration_ = AceType::MakeRefPtr<Decoration>();
1399 }
1400 Border border = backDecoration_->GetBorder();
1401 if (helper.Set(width, &border)) {
1402 backDecoration_->SetBorder(border);
1403 MarkNeedLayout();
1404 }
1405 }
1406
GetBorderWidth(const BorderEdgeHelper & helper) const1407 double RenderBox::GetBorderWidth(const BorderEdgeHelper& helper) const
1408 {
1409 if (backDecoration_ != nullptr) {
1410 return helper.Get(backDecoration_->GetBorder()).GetWidth().Value();
1411 }
1412 return 0.0;
1413 }
1414
SetBorderColor(const Color & color,const BorderEdgeHelper & helper)1415 void RenderBox::SetBorderColor(const Color& color, const BorderEdgeHelper& helper)
1416 {
1417 if (backDecoration_ == nullptr) {
1418 backDecoration_ = AceType::MakeRefPtr<Decoration>();
1419 }
1420 Border border = backDecoration_->GetBorder();
1421 if (helper.Set(color, &border)) {
1422 backDecoration_->SetBorder(border);
1423 MarkNeedLayout();
1424 }
1425 }
1426
GetBorderColor(const BorderEdgeHelper & helper) const1427 Color RenderBox::GetBorderColor(const BorderEdgeHelper& helper) const
1428 {
1429 if (backDecoration_) {
1430 return helper.Get(backDecoration_->GetBorder()).GetColor();
1431 }
1432 return {};
1433 }
1434
SetBorderStyle(BorderStyle borderStyle,const BorderEdgeHelper & helper)1435 void RenderBox::SetBorderStyle(BorderStyle borderStyle, const BorderEdgeHelper& helper)
1436 {
1437 if (backDecoration_ == nullptr) {
1438 backDecoration_ = AceType::MakeRefPtr<Decoration>();
1439 }
1440 Border border = backDecoration_->GetBorder();
1441 if (helper.Set(borderStyle, &border)) {
1442 backDecoration_->SetBorder(border);
1443 MarkNeedLayout();
1444 }
1445 }
1446
GetBorderStyle(const BorderEdgeHelper & helper) const1447 BorderStyle RenderBox::GetBorderStyle(const BorderEdgeHelper& helper) const
1448 {
1449 if (backDecoration_) {
1450 return helper.Get(backDecoration_->GetBorder()).GetBorderStyle();
1451 }
1452 return BorderStyle::NONE;
1453 }
1454
SetBorderRadius(double radius,const BorderRadiusHelper & helper)1455 void RenderBox::SetBorderRadius(double radius, const BorderRadiusHelper& helper)
1456 {
1457 if (backDecoration_ == nullptr) {
1458 backDecoration_ = AceType::MakeRefPtr<Decoration>();
1459 }
1460 Border border = backDecoration_->GetBorder();
1461 if (helper.Set(radius, &border)) {
1462 backDecoration_->SetBorder(border);
1463 MarkNeedLayout();
1464 }
1465 }
1466
GetBorderRadius(const BorderRadiusHelper & helper) const1467 double RenderBox::GetBorderRadius(const BorderRadiusHelper& helper) const
1468 {
1469 if (backDecoration_) {
1470 return helper.Get(backDecoration_->GetBorder());
1471 }
1472 return 0.0;
1473 }
1474
SetBlurRadius(const AnimatableDimension & radius)1475 void RenderBox::SetBlurRadius(const AnimatableDimension& radius)
1476 {
1477 if (frontDecoration_ == nullptr) {
1478 frontDecoration_ = AceType::MakeRefPtr<Decoration>();
1479 }
1480 if (!NearEqual(frontDecoration_->GetBlurRadius().Value(), radius.Value())) {
1481 frontDecoration_->SetBlurRadius(radius);
1482 MarkNeedRender();
1483 }
1484 }
1485
GetBlurRadius() const1486 AnimatableDimension RenderBox::GetBlurRadius() const
1487 {
1488 if (frontDecoration_) {
1489 return frontDecoration_->GetBlurRadius();
1490 }
1491 return AnimatableDimension(0.0, DimensionUnit::PX);
1492 }
1493
SetBackdropRadius(const AnimatableDimension & radius)1494 void RenderBox::SetBackdropRadius(const AnimatableDimension& radius)
1495 {
1496 if (backDecoration_ == nullptr) {
1497 backDecoration_ = AceType::MakeRefPtr<Decoration>();
1498 }
1499 if (!NearEqual(backDecoration_->GetBlurRadius().Value(), radius.Value())) {
1500 backDecoration_->SetBlurRadius(radius);
1501 MarkNeedRender();
1502 }
1503 }
1504
GetBackdropRadius() const1505 AnimatableDimension RenderBox::GetBackdropRadius() const
1506 {
1507 if (backDecoration_) {
1508 return backDecoration_->GetBlurRadius();
1509 }
1510 return AnimatableDimension(0.0, DimensionUnit::PX);
1511 }
1512
SetWindowBlurProgress(double progress)1513 void RenderBox::SetWindowBlurProgress(double progress)
1514 {
1515 if (backDecoration_ == nullptr) {
1516 backDecoration_ = AceType::MakeRefPtr<Decoration>();
1517 }
1518 if (!NearEqual(backDecoration_->GetWindowBlurProgress(), progress)) {
1519 backDecoration_->SetWindowBlurProgress(progress);
1520 MarkNeedRender();
1521 }
1522 }
1523
GetWindowBlurProgress() const1524 double RenderBox::GetWindowBlurProgress() const
1525 {
1526 if (backDecoration_) {
1527 return backDecoration_->GetWindowBlurProgress();
1528 }
1529 return 0.0;
1530 }
1531
AddRecognizerToResult(const Offset & coordinateOffset,const TouchRestrict & touchRestrict,TouchTestResult & result)1532 void RenderBox::AddRecognizerToResult(
1533 const Offset& coordinateOffset, const TouchRestrict& touchRestrict, TouchTestResult& result)
1534 {
1535 if (!ExistGestureRecognizer()) {
1536 return;
1537 }
1538
1539 bool ignoreInternal = false;
1540 for (int i = MAX_GESTURE_SIZE - 1; i >= 0; i--) {
1541 if (recognizers_[i]) {
1542 ignoreInternal = recognizers_[i]->GetPriorityMask() == GestureMask::IgnoreInternal;
1543 if (ignoreInternal) {
1544 break;
1545 }
1546 }
1547 }
1548
1549 if (ignoreInternal) {
1550 auto iter = result.begin();
1551 while (iter != result.end()) {
1552 auto recognizer = AceType::DynamicCast<GestureRecognizer>(*iter);
1553 if (!recognizer) {
1554 iter++;
1555 continue;
1556 }
1557
1558 if (!recognizer->GetIsExternalGesture()) {
1559 iter++;
1560 continue;
1561 }
1562 iter = result.erase(iter);
1563 }
1564 }
1565
1566 for (int i = MAX_GESTURE_SIZE - 1; i >= 0; i--) {
1567 if (recognizers_[i]) {
1568 LOGD("OnTouchTestHit add recognizer to result %{public}s", AceType::TypeName(recognizers_[i]));
1569 recognizers_[i]->SetCoordinateOffset(coordinateOffset);
1570 result.emplace_back(recognizers_[i]);
1571 }
1572 }
1573 }
1574
OnTouchTestHit(const Offset & coordinateOffset,const TouchRestrict & touchRestrict,TouchTestResult & result)1575 void RenderBox::OnTouchTestHit(
1576 const Offset& coordinateOffset, const TouchRestrict& touchRestrict, TouchTestResult& result)
1577 {
1578 AddRecognizerToResult(coordinateOffset, touchRestrict, result);
1579 if (touchRecognizer_) {
1580 touchRecognizer_->SetCoordinateOffset(coordinateOffset);
1581 result.emplace_back(touchRecognizer_);
1582 MarkIsNotSiblingAddRecognizerToResult(false);
1583 }
1584 if (onClick_) {
1585 onClick_->SetCoordinateOffset(coordinateOffset);
1586 result.emplace_back(onClick_);
1587 MarkIsNotSiblingAddRecognizerToResult(true);
1588 }
1589 if (onLongPress_ && dragDropGesture_) {
1590 std::vector<RefPtr<GestureRecognizer>> recognizers { onLongPress_, dragDropGesture_ };
1591 parallelRecognizer_ = AceType::MakeRefPtr<OHOS::Ace::ParallelRecognizer>(recognizers);
1592 parallelRecognizer_->SetCoordinateOffset(coordinateOffset);
1593 result.emplace_back(parallelRecognizer_);
1594 MarkIsNotSiblingAddRecognizerToResult(true);
1595 return;
1596 }
1597 if (onLongPress_) {
1598 onLongPress_->SetCoordinateOffset(coordinateOffset);
1599 result.emplace_back(onLongPress_);
1600 MarkIsNotSiblingAddRecognizerToResult(true);
1601 }
1602 if (dragDropGesture_) {
1603 dragDropGesture_->SetCoordinateOffset(coordinateOffset);
1604 result.emplace_back(dragDropGesture_);
1605 MarkIsNotSiblingAddRecognizerToResult(true);
1606 }
1607 }
1608
UpdateGestureRecognizer(const std::array<RefPtr<Gesture>,MAX_GESTURE_SIZE> & gestures)1609 void RenderBox::UpdateGestureRecognizer(const std::array<RefPtr<Gesture>, MAX_GESTURE_SIZE>& gestures)
1610 {
1611 // Considering 4 cases:
1612 // 1. new gesture == null && old recognizer == null --> do nothing
1613 // 2. new gesture != null && old recognizer == null --> create new recognizer configured with new gesture
1614 // 3. new gesture == null && old recognizer != null --> remove old recognizer
1615 // 4. new gesture != null && old recognizer != null --> update old recognizer with new configuration if
1616 // possible(determined by[GestureRecognizer::ReconcileFrom]), or remove the old recognizer and create new
1617 // one configured with new gesture.
1618 for (size_t i = 0; i < gestures.size(); i++) {
1619 if (!gestures[i]) {
1620 recognizers_[i] = nullptr;
1621 continue;
1622 }
1623 auto recognizer = gestures[i]->CreateRecognizer(context_);
1624 if (recognizer) {
1625 recognizer->SetIsExternalGesture(true);
1626 if (!recognizers_[i] || !recognizers_[i]->ReconcileFrom(recognizer)) {
1627 recognizers_[i] = recognizer;
1628 }
1629 }
1630 }
1631 }
1632
ExistGestureRecognizer()1633 bool RenderBox::ExistGestureRecognizer()
1634 {
1635 for (size_t i = 0; i < recognizers_.size(); i++) {
1636 if (recognizers_[i]) {
1637 return true;
1638 }
1639 }
1640
1641 return false;
1642 }
1643
HandleRemoteMessage(const ClickInfo & clickInfo)1644 void RenderBox::HandleRemoteMessage(const ClickInfo& clickInfo)
1645 {
1646 if (remoteMessageEvent_) {
1647 remoteMessageEvent_(std::make_shared<ClickInfo>(clickInfo));
1648 }
1649 }
1650
OnStatusStyleChanged(const VisualState state)1651 void RenderBox::OnStatusStyleChanged(const VisualState state)
1652 {
1653 RenderBoxBase::OnStatusStyleChanged(state);
1654
1655 if (stateAttributeList_ == nullptr) {
1656 return;
1657 }
1658
1659 LOGD("state %{public}d attr count %{public}d", state,
1660 static_cast<int32_t>(stateAttributeList_->GetAttributesForState(state).size()));
1661 bool updated = false;
1662 for (auto& attribute : stateAttributeList_->GetAttributesForState(state)) {
1663 updated = true;
1664 switch (attribute->id_) {
1665 case BoxStateAttribute::COLOR: {
1666 LOGD("Setting COLOR for state %{public}d", attribute->id_);
1667 auto colorState =
1668 AceType::DynamicCast<StateAttributeValue<BoxStateAttribute, AnimatableColor>>(attribute);
1669 GetBackDecoration()->SetBackgroundColor(colorState->value_);
1670 } break;
1671
1672 case BoxStateAttribute::BORDER_COLOR: {
1673 LOGD("Setting BORDER_COLOR for state %{public}d", attribute->id_);
1674 auto colorState =
1675 AceType::DynamicCast<StateAttributeValue<BoxStateAttribute, AnimatableColor>>(attribute);
1676 BoxComponentHelper::SetBorderColor(GetBackDecoration(), colorState->value_);
1677 } break;
1678
1679 case BoxStateAttribute::BORDER_RADIUS: {
1680 LOGD("Setting BORDER_RADIUS for state %{public}d", attribute->id_);
1681 auto radiusState =
1682 AceType::DynamicCast<StateAttributeValue<BoxStateAttribute, AnimatableDimension>>(attribute);
1683 BoxComponentHelper::SetBorderRadius(GetBackDecoration(), radiusState->value_);
1684 } break;
1685
1686 case BoxStateAttribute::BORDER_STYLE: {
1687 LOGD("Setting BORDER_STYLE for state %{public}d", attribute->id_);
1688 auto attributeStateValue =
1689 AceType::DynamicCast<StateAttributeValue<BoxStateAttribute, BorderStyle>>(attribute);
1690 BoxComponentHelper::SetBorderStyle(GetBackDecoration(), attributeStateValue->value_);
1691 } break;
1692
1693 case BoxStateAttribute::BORDER_WIDTH: {
1694 auto widthState =
1695 AceType::DynamicCast<StateAttributeValue<BoxStateAttribute, AnimatableDimension>>(attribute);
1696 LOGD("Setting BORDER_WIDTH for state %{public}d to %{public}lf", state, widthState->value_.Value());
1697 BoxComponentHelper::SetBorderWidth(GetBackDecoration(), widthState->value_);
1698 } break;
1699
1700 case BoxStateAttribute::HEIGHT: {
1701 auto valueState = AceType::DynamicCast<StateAttributeValue<BoxStateAttribute, Dimension>>(attribute);
1702 LOGD("Setting BORDER_WIDTH for state %{public}d to %{public}lf", attribute->id_,
1703 valueState->value_.Value());
1704 height_ = valueState->value_;
1705 } break;
1706
1707 case BoxStateAttribute::WIDTH: {
1708 auto valueState =
1709 AceType::DynamicCast<StateAttributeValue<BoxStateAttribute, AnimatableDimension>>(attribute);
1710 LOGD("Setting BORDER_WIDTH for state %{public}d to %{public}lf", state, valueState->value_.Value());
1711 width_ = valueState->value_;
1712 } break;
1713
1714 case BoxStateAttribute::ASPECT_RATIO: {
1715 LOGD("Setting ASPECT Ration state %{public}d", attribute->id_);
1716 auto valueState =
1717 AceType::DynamicCast<StateAttributeValue<BoxStateAttribute, AnimatableDimension>>(attribute);
1718 SetAspectRatio(valueState->value_);
1719 } break;
1720
1721 case BoxStateAttribute::BORDER: {
1722 // We replace support for border object with updates to border components:
1723 // color, style, width, radius
1724 // The reason - developer does not have to provide all border properties
1725 // when border is set.
1726 // See JSViewAbstract::JsBorder for details
1727 } break;
1728
1729 case BoxStateAttribute::GRADIENT: {
1730 auto gradientState = AceType::DynamicCast<StateAttributeValue<BoxStateAttribute, Gradient>>(attribute);
1731 LOGD("Setting Gradient state %{public}d", state);
1732 GetBackDecoration()->SetGradient(gradientState->value_);
1733 } break;
1734 default:
1735 break;
1736 }
1737 }
1738 if (updated) {
1739 MarkNeedLayout();
1740 }
1741 };
1742
1743 } // namespace OHOS::Ace
1744