• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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/container_modal/container_modal_element.h"
17 
18 #include "base/memory/ace_type.h"
19 #include "core/components/box/box_element.h"
20 #include "core/components/box/render_box.h"
21 #include "core/components/clip/clip_element.h"
22 #include "core/components/clip/render_clip.h"
23 #include "core/components/container_modal/container_modal_constants.h"
24 #include "core/components/container_modal/render_container_modal.h"
25 #include "core/components/flex/flex_element.h"
26 #include "core/components/padding/render_padding.h"
27 #include "core/gestures/tap_gesture.h"
28 #include "core/pipeline/base/render_node.h"
29 
30 namespace OHOS::Ace {
31 namespace {
32 
33 constexpr uint32_t COLUMN_CHILD_NUM = 2;
34 constexpr uint32_t TITLE_POSITION = 1;
35 constexpr uint32_t SPLIT_BUTTON_POSITION = 2;
36 constexpr uint32_t TITLE_POPUP_TIME = 200;        // 200ms
37 constexpr double MOUSE_MOVE_POPUP_DISTANCE = 5.0; // 5.0px
38 constexpr double MOVE_POPUP_DISTANCE_X = 10.0;    // 10.0px
39 constexpr double MOVE_POPUP_DISTANCE_Y = 20.0;    // 20.0px
40 constexpr double TITLE_POPUP_DISTANCE = 37.0;     // 37vp height of title
41 
42 } // namespace
43 
GetStackElement() const44 RefPtr<StackElement> ContainerModalElement::GetStackElement() const
45 {
46     auto containerBox = AceType::DynamicCast<BoxElement>(GetFirstChild());
47     if (!containerBox) {
48         LOGE("Get stack element failed, container box element is null!");
49         return {};
50     }
51 
52     // The first stack is not what we need.
53     auto stackElement = AceType::DynamicCast<StackElement>(containerBox->GetFirstChild());
54     if (!stackElement) {
55         LOGE("Get stack element failed, stack element is null!");
56         return {};
57     }
58 
59     auto column = AceType::DynamicCast<ColumnElement>(stackElement->GetFirstChild());
60     if (!column || column->GetChildren().size() != COLUMN_CHILD_NUM) {
61         // column should have 2 children, title and content.
62         LOGE("Get stack element failed, column is null or child size error!");
63         return {};
64     }
65 
66     // Get second child : content
67     auto clip = AceType::DynamicCast<ClipElement>(column->GetLastChild());
68     if (!clip) {
69         LOGE("Get stack element failed, clip element is null!");
70         return {};
71     }
72 
73     auto contentBox = AceType::DynamicCast<BoxElement>(clip->GetFirstChild());
74     if (!contentBox) {
75         LOGE("Get stack element failed, content box element is null!");
76         return {};
77     }
78 
79     auto stack = contentBox->GetFirstChild();
80     if (!stack || !AceType::InstanceOf<StackElement>(stack)) {
81         LOGE("Get stack element failed, stack is null or type error!");
82         return {};
83     }
84 
85     return AceType::DynamicCast<StackElement>(stack);
86 }
87 
GetOverlayElement() const88 RefPtr<OverlayElement> ContainerModalElement::GetOverlayElement() const
89 {
90     auto stack = GetStackElement();
91     if (!stack) {
92         LOGE("Get overlay element failed, stack element is null");
93         return {};
94     }
95 
96     for (const auto& child : stack->GetChildren()) {
97         if (child && AceType::InstanceOf<OverlayElement>(child)) {
98             return AceType::DynamicCast<OverlayElement>(child);
99         }
100     }
101     LOGE("Get overlay element failed, all children of stack element do not meet the requirements");
102     return {};
103 }
104 
GetStageElement() const105 RefPtr<StageElement> ContainerModalElement::GetStageElement() const
106 {
107     auto stack = GetStackElement();
108     if (!stack) {
109         LOGE("Get stage element failed, stack element is null");
110         return {};
111     }
112     for (const auto& child : stack->GetChildren()) {
113         if (child && AceType::InstanceOf<StageElement>(child)) {
114             return AceType::DynamicCast<StageElement>(child);
115         }
116     }
117     LOGE("Get stage element failed, all children of stack element do not meet the requirements");
118     return {};
119 }
120 
ShowTitle(bool isShow,bool hasDeco,bool needUpdate)121 void ContainerModalElement::ShowTitle(bool isShow, bool hasDeco, bool needUpdate)
122 {
123     auto containerBox = AceType::DynamicCast<BoxElement>(GetFirstChild());
124     if (!containerBox) {
125         LOGE("ContainerModalElement showTitle failed, container box element is null!");
126         return;
127     }
128     auto context = context_.Upgrade();
129     if (!context) {
130         LOGE("ContainerModalElement showTitle failed, context is null.");
131         return;
132     }
133     windowMode_ = context->GetWindowManager()->GetWindowMode();
134     hasDeco_ = hasDeco;
135     LOGI("ShowTitle isShow: %{public}d, windowMode: %{public}d, hasDeco: %{public}d", isShow, windowMode_, hasDeco_);
136     if (!hasDeco_) {
137         isShow = false;
138     }
139 
140     // set container window show state to RS
141     context->SetContainerWindow(isShow);
142 
143     // full screen need to hide border and padding.
144     auto containerRenderBox = AceType::DynamicCast<RenderBox>(containerBox->GetRenderNode());
145     if (containerRenderBox) {
146         auto containerDecoration = containerRenderBox->GetBackDecoration();
147         Edge padding = Edge();
148         Border outerBorder = Border();
149         if (isShow) {
150             outerBorder.SetBorderRadius(Radius(CONTAINER_OUTER_RADIUS));
151             outerBorder.SetColor(CONTAINER_BORDER_COLOR);
152             outerBorder.SetWidth(CONTAINER_BORDER_WIDTH);
153             padding = Edge(CONTENT_PADDING, Dimension(0.0), CONTENT_PADDING, CONTENT_PADDING);
154         }
155         containerDecoration->SetBorder(outerBorder);
156         containerRenderBox->SetBackDecoration(containerDecoration);
157         containerRenderBox->SetPadding(padding);
158     }
159 
160     auto stackElement = AceType::DynamicCast<StackElement>(containerBox->GetFirstChild());
161     if (!stackElement) {
162         LOGE("ContainerModalElement showTitle failed, stack element is null!");
163         return;
164     }
165 
166     auto column = AceType::DynamicCast<ColumnElement>(stackElement->GetFirstChild());
167     if (!column || column->GetChildren().size() != COLUMN_CHILD_NUM) {
168         // column should have 2 children, title and content.
169         LOGE("ContainerModalElement showTitle failed, column  element is null or children size error!");
170         return;
171     }
172 
173     // full screen need to hide content border radius.
174     auto clip = AceType::DynamicCast<ClipElement>(column->GetLastChild());
175     if (!clip) {
176         LOGE("ContainerModalElement showTitle failed, clip element is null!");
177         return;
178     }
179     if (!contentBox_) {
180         contentBox_ = AceType::DynamicCast<BoxElement>(clip->GetFirstChild());
181     }
182     auto renderClip = AceType::DynamicCast<RenderClip>(clip->GetRenderNode());
183     if (renderClip) {
184         isShow ? renderClip->SetClipRadius(Radius(CONTAINER_INNER_RADIUS)) : renderClip->SetClipRadius(Radius(0.0));
185     }
186 
187     // Get first child : title
188     auto display = AceType::DynamicCast<DisplayElement>(column->GetFirstChild());
189     if (!display) {
190         LOGE("ContainerModalElement showTitle failed,, display element is null.");
191         return;
192     }
193     auto renderDisplay = AceType::DynamicCast<RenderDisplay>(display->GetRenderNode());
194     if (renderDisplay) {
195         renderDisplay->UpdateVisibleType(isShow ? VisibleType::VISIBLE : VisibleType::GONE);
196     }
197     ChangeFloatingTitleIcon();
198 
199     // hide floating title anyway.
200     if (floatingTitleDisplay_) {
201         floatingTitleDisplay_->UpdateVisibleType(VisibleType::GONE);
202     }
203 }
204 
PerformBuild()205 void ContainerModalElement::PerformBuild()
206 {
207     SoleChildElement::PerformBuild();
208     if (!controller_) {
209         controller_ = CREATE_ANIMATOR(context_);
210         controller_->SetDuration(TITLE_POPUP_TIME);
211         controller_->SetFillMode(FillMode::FORWARDS);
212         auto translateY = AceType::MakeRefPtr<CurveAnimation<DimensionOffset>>(
213             DimensionOffset(Dimension(), Dimension(-TITLE_POPUP_DISTANCE * density_)),
214             DimensionOffset(Dimension(), Dimension()), Curves::FRICTION);
215         TweenOption option;
216         option.SetTranslateAnimations(AnimationType::TRANSLATE_Y, translateY);
217         auto containerBox = AceType::DynamicCast<BoxElement>(GetFirstChild());
218         if (!containerBox) {
219             LOGE("ContainerModalElement PerformBuild failed, container box element is null!");
220             return;
221         }
222 
223         auto stackElement = AceType::DynamicCast<StackElement>(containerBox->GetFirstChild());
224         if (!stackElement) {
225             LOGE("ContainerModalElement PerformBuild failed, stack element is null!");
226             return;
227         }
228         auto column = AceType::DynamicCast<ColumnElement>(stackElement->GetFirstChild());
229         if (!column || column->GetChildren().size() != COLUMN_CHILD_NUM) {
230             // column should have 2 children, title and content.
231             LOGE("ContainerModalElement PerformBuild failed, column  element is null or children size error!");
232             return;
233         }
234 
235         auto titleDisplay = AceType::DynamicCast<DisplayElement>(column->GetFirstChild());
236         if (titleDisplay && titleDisplay->GetFirstChild()) {
237             titleBox_ = AceType::DynamicCast<BoxElement>(titleDisplay->GetFirstChild()->GetFirstChild());
238         }
239 
240         auto tween = AceType::DynamicCast<TweenElement>(stackElement->GetLastChild());
241         if (!tween) {
242             LOGE("ContainerModalElement PerformBuild failed, tween element is null.");
243             return;
244         }
245         if (tween->GetContentElement()) {
246             floatingTitleBox_ = AceType::DynamicCast<BoxElement>(tween->GetContentElement()->GetFirstChild());
247         }
248 
249         auto display = AceType::DynamicCast<DisplayElement>(tween->GetFirstChild());
250         if (display && !floatingTitleDisplay_) {
251             floatingTitleDisplay_ = AceType::DynamicCast<RenderDisplay>(display->GetRenderNode());
252             if (floatingTitleDisplay_) {
253                 floatingTitleDisplay_->UpdateVisibleType(VisibleType::GONE);
254             }
255         }
256         tween->SetController(controller_);
257         tween->SetOption(option);
258         tween->ApplyKeyframes();
259     }
260 
261     ChangeTitleIcon();
262 
263     // The first time it starts up, it needs to hide title if mode as follows.
264     windowMode_ = context_.Upgrade()->GetWindowManager()->GetWindowMode();
265     ShowTitle(windowMode_ == WindowMode::WINDOW_MODE_FLOATING, hasDeco_);
266 }
267 
FlushReload()268 void ContainerModalElement::FlushReload()
269 {
270     auto containerBox = AceType::DynamicCast<BoxElement>(GetFirstChild());
271     if (!containerBox) {
272         LOGE("ContainerModalElement WindowFocus failed, container box element is null!");
273         return;
274     }
275     auto containerRenderBox = AceType::DynamicCast<RenderBox>(containerBox->GetRenderNode());
276     if (containerRenderBox) {
277         auto containerDecoration = containerRenderBox->GetBackDecoration();
278         containerDecoration->SetBackgroundColor(
279             windowFocus_ ? CONTAINER_BACKGROUND_COLOR : CONTAINER_BACKGROUND_COLOR_LOST_FOCUS);
280         auto border = containerDecoration->GetBorder();
281         border.SetColor(windowFocus_ ? CONTAINER_BORDER_COLOR : CONTAINER_BORDER_COLOR_LOST_FOCUS);
282         containerDecoration->SetBorder(border);
283         containerRenderBox->SetBackDecoration(containerDecoration);
284     }
285     if (windowMode_ == WindowMode::WINDOW_MODE_FULLSCREEN || windowMode_ == WindowMode::WINDOW_MODE_SPLIT_PRIMARY ||
286         windowMode_ == WindowMode::WINDOW_MODE_SPLIT_SECONDARY) {
287         ChangeFloatingTitleIcon(windowFocus_);
288         return;
289     }
290     ChangeTitleIcon(windowFocus_);
291 }
292 
Update()293 void ContainerModalElement::Update()
294 {
295     RenderElement::Update();
296 
297     containerModalComponent_ = AceType::DynamicCast<ContainerModalComponent>(component_);
298     if (!containerModalComponent_) {
299         LOGE("ContainerModalElement update failed, container modal component is null.");
300         return;
301     }
302     auto containerBox = AceType::DynamicCast<BoxComponent>(containerModalComponent_->GetChild());
303     if (!containerBox) {
304         LOGE("ContainerModalElement update failed, container box component is null.");
305         return;
306     }
307     auto context = context_.Upgrade();
308     if (context) {
309         density_ = (float)context->GetDensity();
310     }
311 
312     containerBox->SetOnTouchDownId([weak = WeakClaim(this), context = context_](const TouchEventInfo& info) {
313         auto containerElement = weak.Upgrade();
314         auto pipeline = context.Upgrade();
315         if (!pipeline || !containerElement || !containerElement->hasDeco_) {
316             return;
317         }
318         auto viewScale = pipeline->GetViewScale();
319         if (info.GetChangedTouches().begin()->GetGlobalLocation().GetY() * viewScale <=
320             (TITLE_POPUP_DISTANCE * containerElement->density_)) {
321             containerElement->moveX_ = info.GetChangedTouches().begin()->GetGlobalLocation().GetX() * viewScale;
322             containerElement->moveY_ = info.GetChangedTouches().begin()->GetGlobalLocation().GetY() * viewScale;
323             return;
324         }
325 
326         // touch other area to hide floating title
327         if (containerElement->CanHideFloatingTitle()) {
328             containerElement->controller_->AddStopListener([weak] {
329                 auto container = weak.Upgrade();
330                 if (container && container->floatingTitleDisplay_) {
331                     container->floatingTitleDisplay_->UpdateVisibleType(VisibleType::GONE);
332                 }
333             });
334             containerElement->controller_->Backward();
335         }
336     });
337 
338     // touch top to pop-up title bar.
339     containerBox->SetOnTouchMoveId([weak = WeakClaim(this), context = context_](const TouchEventInfo& info) {
340         auto containerElement = weak.Upgrade();
341         auto pipeline = context.Upgrade();
342         if (!pipeline || !containerElement || !containerElement->hasDeco_ ||
343             !containerElement->CanShowFloatingTitle()) {
344             return;
345         }
346         auto viewScale = pipeline->GetViewScale();
347         if (info.GetChangedTouches().begin()->GetGlobalLocation().GetY() * viewScale >
348             (TITLE_POPUP_DISTANCE * containerElement->density_)) {
349             return;
350         }
351         auto deltaMoveX =
352             fabs(info.GetChangedTouches().begin()->GetGlobalLocation().GetX() * viewScale - containerElement->moveX_);
353         auto deltaMoveY =
354             info.GetChangedTouches().begin()->GetGlobalLocation().GetY() * viewScale - containerElement->moveY_;
355         if (deltaMoveX <= MOVE_POPUP_DISTANCE_X && deltaMoveY >= MOVE_POPUP_DISTANCE_Y) {
356             containerElement->floatingTitleDisplay_->UpdateVisibleType(VisibleType::VISIBLE);
357             containerElement->controller_->ClearStopListeners();
358             containerElement->controller_->AddStopListener([weak] {
359                 auto container = weak.Upgrade();
360                 container->SetTitleAccessibilityNodeOffset();
361             });
362             containerElement->controller_->Forward();
363         }
364     });
365 
366     // mouse move top to pop up title bar and move other area to hide title bar.
367     containerBox->SetOnMouseId([weak = WeakClaim(this), context = context_](MouseInfo& info) {
368         auto containerElement = weak.Upgrade();
369         auto pipeline = context.Upgrade();
370         if (!pipeline || !containerElement || !containerElement->hasDeco_ || info.GetAction() != MouseAction::MOVE) {
371             return;
372         }
373         auto viewScale = pipeline->GetViewScale();
374         if (info.GetLocalLocation().GetY() * viewScale <= MOUSE_MOVE_POPUP_DISTANCE &&
375             containerElement->CanShowFloatingTitle()) {
376             containerElement->floatingTitleDisplay_->UpdateVisibleType(VisibleType::VISIBLE);
377             containerElement->controller_->ClearStopListeners();
378             containerElement->controller_->AddStopListener([weak] {
379                 auto container = weak.Upgrade();
380                 container->SetTitleAccessibilityNodeOffset();
381             });
382             containerElement->controller_->Forward();
383         }
384         if (info.GetLocalLocation().GetY() * viewScale > (TITLE_POPUP_DISTANCE * containerElement->density_) &&
385             containerElement->CanHideFloatingTitle()) {
386             containerElement->controller_->AddStopListener([weak] {
387                 auto container = weak.Upgrade();
388                 if (container && container->floatingTitleDisplay_) {
389                     container->floatingTitleDisplay_->UpdateVisibleType(VisibleType::GONE);
390                 }
391             });
392             containerElement->controller_->Backward();
393         }
394     });
395 }
396 
CanShowFloatingTitle()397 bool ContainerModalElement::CanShowFloatingTitle()
398 {
399     if (!floatingTitleDisplay_ || !controller_) {
400         LOGI("Show floating title failed, floatingTitleDisplay or controller is null.");
401         return false;
402     }
403     if (windowMode_ != WindowMode::WINDOW_MODE_FULLSCREEN && windowMode_ != WindowMode::WINDOW_MODE_SPLIT_PRIMARY &&
404         windowMode_ != WindowMode::WINDOW_MODE_SPLIT_SECONDARY) {
405         LOGI("Window is not full screen or split screen, can not show floating title.");
406         return false;
407     }
408     if (floatingTitleDisplay_->GetVisible()) {
409         LOGI("Floating tittle is visible now, no need to show again.");
410         return false;
411     }
412     return true;
413 }
414 
CanHideFloatingTitle()415 bool ContainerModalElement::CanHideFloatingTitle()
416 {
417     if (!floatingTitleDisplay_ || !controller_) {
418         LOGI("Hide floating title failed, floatingTitleDisplay or controller is null.");
419         return false;
420     }
421     if (!floatingTitleDisplay_->GetVisible()) {
422         LOGI("Hide floating title failed, title is not visible.");
423         return false;
424     }
425     return true;
426 }
427 
ChangeFloatingTitleIcon(bool isFocus)428 void ContainerModalElement::ChangeFloatingTitleIcon(bool isFocus)
429 {
430     if (!floatingTitleBox_ || !containerModalComponent_) {
431         LOGE("ChangeFloatingTitleIcon failed.");
432         return;
433     }
434     auto renderFloatingTitleBox = AceType::DynamicCast<RenderBox>(floatingTitleBox_->GetRenderNode());
435     if (!renderFloatingTitleBox) {
436         LOGE("ChangeFloatingTitleIcon failed, render floating title box is null.");
437         return;
438     }
439     auto backDecoration = renderFloatingTitleBox->GetBackDecoration();
440     backDecoration->SetBackgroundColor(isFocus ? CONTAINER_BACKGROUND_COLOR : CONTAINER_BACKGROUND_COLOR_LOST_FOCUS);
441     renderFloatingTitleBox->SetBackDecoration(backDecoration);
442 
443     auto rowElement = AceType::DynamicCast<RowElement>(floatingTitleBox_->GetFirstChild());
444     if (!rowElement) {
445         LOGE("ChangeFloatingTitleIcon failed, row element is null.");
446         return;
447     }
448     RefPtr<RenderPadding> splitButton = nullptr;
449     if (!containerModalComponent_->GetSplitButtonHide()) {
450         auto renderRow = AceType::DynamicCast<RenderFlex>(rowElement->GetRenderNode());
451         if (!renderRow) {
452             LOGE("ChangeFloatingTitleIcon failed, renderRow is null.");
453             return;
454         }
455         auto iterator = renderRow->GetChildren().begin();
456         std::advance(iterator, SPLIT_BUTTON_POSITION);
457         splitButton = AceType::DynamicCast<RenderPadding>(*iterator);
458     }
459 
460     auto floatingTitleChildrenRow = AceType::MakeRefPtr<RowComponent>(FlexAlign::FLEX_START, FlexAlign::CENTER,
461         containerModalComponent_->BuildTitleChildren(true, isFocus, windowMode_ == WindowMode::WINDOW_MODE_FULLSCREEN));
462     floatingTitleChildrenRow->SetUpdateType(UpdateType::REBUILD);
463     rowElement->SetUpdateComponent(floatingTitleChildrenRow);
464 
465     if (splitButton) {
466         splitButton->SetHidden(windowMode_ == WindowMode::WINDOW_MODE_SPLIT_PRIMARY);
467     }
468 }
469 
ChangeTitleIcon(bool isFocus)470 void ContainerModalElement::ChangeTitleIcon(bool isFocus)
471 {
472     if (!titleBox_ || !containerModalComponent_) {
473         LOGE("ChangeTitleIcon failed.");
474         return;
475     }
476     auto rowElement = AceType::DynamicCast<RowElement>(titleBox_->GetFirstChild());
477     if (!rowElement) {
478         LOGE("ChangeTitleIcon failed, row element is null.");
479         return;
480     }
481     auto titleChildrenRow = AceType::MakeRefPtr<RowComponent>(
482         FlexAlign::FLEX_START, FlexAlign::CENTER, containerModalComponent_->BuildTitleChildren(false, isFocus));
483     titleChildrenRow->SetUpdateType(UpdateType::REBUILD);
484     rowElement->SetUpdateComponent(titleChildrenRow);
485 }
486 
WindowFocus(bool isFocus)487 void ContainerModalElement::WindowFocus(bool isFocus)
488 {
489     windowFocus_ = isFocus;
490     FlushReload();
491 }
492 
SetAppBgColor(const Color & color)493 void ContainerModalElement::SetAppBgColor(const Color& color)
494 {
495     if (!contentBox_) {
496         LOGE("SetAppBgColor failed, contentBox_ is nullptr.");
497         return;
498     }
499     auto renderContentBox = AceType::DynamicCast<RenderBox>(contentBox_->GetRenderNode());
500     if (!renderContentBox) {
501         LOGE("SetAppBgColor failed, renderContentBox is nullptr.");
502         return;
503     }
504     auto backDecoration = renderContentBox->GetBackDecoration();
505     backDecoration->SetBackgroundColor(color);
506     renderContentBox->SetBackDecoration(backDecoration);
507 }
508 
SetTitleButtonHide(bool hideSplit,bool hideMaximize,bool hideMinimize)509 void ContainerModalElement::SetTitleButtonHide(bool hideSplit, bool hideMaximize, bool hideMinimize)
510 {
511     if (!titleBox_ || !floatingTitleBox_ || !containerModalComponent_) {
512         LOGE("titleBox_  floatingTitleBox_ or containerModalComponent_ is null.");
513         return;
514     }
515     auto rowElement = AceType::DynamicCast<RowElement>(titleBox_->GetFirstChild());
516     if (!rowElement) {
517         LOGE("row element is null.");
518         return;
519     }
520     auto floatingRowElement = AceType::DynamicCast<RowElement>(floatingTitleBox_->GetFirstChild());
521     if (!floatingRowElement) {
522         LOGE("floating row element is null.");
523         return;
524     }
525     containerModalComponent_->SetTitleButtonHide(hideSplit, hideMaximize, hideMinimize);
526 
527     auto titleChildrenRow = AceType::MakeRefPtr<RowComponent>(
528         FlexAlign::FLEX_START, FlexAlign::CENTER, containerModalComponent_->BuildTitleChildren(false, windowFocus_));
529     titleChildrenRow->SetUpdateType(UpdateType::REBUILD);
530     rowElement->SetUpdateComponent(titleChildrenRow);
531 
532     auto floatingTitleChildrenRow = AceType::MakeRefPtr<RowComponent>(
533         FlexAlign::FLEX_START, FlexAlign::CENTER, containerModalComponent_->BuildTitleChildren(true, windowFocus_));
534     floatingTitleChildrenRow->SetUpdateType(UpdateType::REBUILD);
535     floatingRowElement->SetUpdateComponent(floatingTitleChildrenRow);
536 }
537 
SetAppTitle(const std::string & title)538 void ContainerModalElement::SetAppTitle(const std::string& title)
539 {
540     CHECK_NULL_VOID(containerModalComponent_);
541     auto textComponent = containerModalComponent_->GetTitleLabel();
542     CHECK_NULL_VOID(textComponent);
543     if (textComponent->GetData() == title) {
544         LOGI("set same title, skip, title is %{public}s", title.c_str());
545         return;
546     }
547     textComponent->SetData(title);
548     bool isFloatingTitle = windowMode_ != WindowMode::WINDOW_MODE_FLOATING;
549     auto renderTitle = GetTitleRender(isFloatingTitle);
550     CHECK_NULL_VOID(renderTitle);
551     renderTitle->Update(textComponent);
552     renderTitle->MarkNeedRender();
553     LOGI("set app title successfully, title:%{public}s, isFloatingTitle:%{public}d", title.c_str(),
554         static_cast<int>(isFloatingTitle));
555 }
556 
SetAppIcon(const RefPtr<PixelMap> & icon)557 void ContainerModalElement::SetAppIcon(const RefPtr<PixelMap>& icon)
558 {
559     CHECK_NULL_VOID(containerModalComponent_);
560     auto imageComponent = containerModalComponent_->GetTitleIcon();
561     CHECK_NULL_VOID(imageComponent);
562     imageComponent->SetSrc("");
563     imageComponent->SetPixmap(icon);
564     bool isFloatingTitle = windowMode_ != WindowMode::WINDOW_MODE_FLOATING;
565     auto renderIcon = GetIconRender(isFloatingTitle);
566     CHECK_NULL_VOID(renderIcon);
567     renderIcon->Update(imageComponent);
568     renderIcon->MarkNeedRender();
569     LOGI("set app icon successfully, isFloatingTitle:%{public}d", static_cast<int>(isFloatingTitle));
570 }
571 
GetTitleRender(bool isFloatingTitle)572 RefPtr<RenderText> ContainerModalElement::GetTitleRender(bool isFloatingTitle)
573 {
574     auto titleBoxElement = isFloatingTitle ? floatingTitleBox_ : titleBox_;
575     CHECK_NULL_RETURN(titleBoxElement, nullptr);
576     auto rowElement = AceType::DynamicCast<RowElement>(titleBoxElement->GetFirstChild());
577     CHECK_NULL_RETURN(rowElement, nullptr);
578     auto renderRow = AceType::DynamicCast<RenderFlex>(rowElement->GetRenderNode());
579     CHECK_NULL_RETURN(renderRow, nullptr);
580     const auto& children = renderRow->GetChildren();
581     if (children.size() <= TITLE_POSITION) {
582         LOGW("row children size is wrong");
583         return nullptr;
584     }
585     auto iterator = renderRow->GetChildren().begin();
586     std::advance(iterator, TITLE_POSITION);
587     auto title = AceType::DynamicCast<RenderText>(*iterator);
588     return title;
589 }
590 
GetIconRender(bool isFloatingTitle)591 RefPtr<RenderImage> ContainerModalElement::GetIconRender(bool isFloatingTitle)
592 {
593     auto titleBoxElement = isFloatingTitle ? floatingTitleBox_ : titleBox_;
594     CHECK_NULL_RETURN(titleBoxElement, nullptr);
595     auto rowElement = AceType::DynamicCast<RowElement>(titleBoxElement->GetFirstChild());
596     CHECK_NULL_RETURN(rowElement, nullptr);
597     auto renderRow = AceType::DynamicCast<RenderFlex>(rowElement->GetRenderNode());
598     CHECK_NULL_RETURN(renderRow, nullptr);
599     auto renderPadding = AceType::DynamicCast<RenderPadding>(renderRow->GetFirstChild());
600     CHECK_NULL_RETURN(renderPadding, nullptr);
601     auto icon = AceType::DynamicCast<RenderImage>(renderPadding->GetFirstChild());
602     return icon;
603 }
604 
SetTitleAccessibilityNodeOffset()605 void ContainerModalElement::SetTitleAccessibilityNodeOffset()
606 {
607     CHECK_NULL_VOID(floatingTitleBox_);
608     auto floatingTitleBoxRender = AceType::DynamicCast<RenderBox>(floatingTitleBox_->GetRenderNode());
609     if (floatingTitleBoxRender) {
610         auto accessibilityNode = floatingTitleBoxRender->GetAccessibilityNode().Upgrade();
611         if (accessibilityNode) {
612             Offset globalOffset =
613                 (floatingTitleBoxRender->GetGlobalOffsetExternal() + floatingTitleBoxRender->GetMargin().GetOffset()) *
614                 floatingTitleBoxRender->GetContext().Upgrade()->GetViewScale();
615             Offset transformOffset(
616                 globalOffset.GetX() - accessibilityNode->GetLeft(), globalOffset.GetY() - accessibilityNode->GetTop());
617             accessibilityNode->AddOffsetForChildren(transformOffset);
618         }
619     }
620 }
621 
622 } // namespace OHOS::Ace
623