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