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