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