1 /*
2  * Copyright (c) 2021 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/root/render_root.h"
17 
18 #include "root_component.h"
19 #include "core/components/theme/app_theme.h"
20 
21 namespace OHOS::Ace {
22 namespace {
23 
IsShadowModal(const WeakPtr<PipelineContext> & contextWeak)24 bool IsShadowModal(const WeakPtr<PipelineContext>& contextWeak)
25 {
26     auto context = contextWeak.Upgrade();
27     if (!context) {
28         return false;
29     }
30     auto modal = context->GetWindowModal();
31     return (modal == WindowModal::DIALOG_MODAL) || (modal == WindowModal::SEMI_MODAL) ||
32            (modal == WindowModal::SEMI_MODAL_FULL_SCREEN);
33 }
34 
35 } // namespace
36 
RenderRoot()37 RenderRoot::RenderRoot() : RenderNode(true) {}
38 
Update(const RefPtr<Component> & component)39 void RenderRoot::Update(const RefPtr<Component>& component)
40 {
41     if (!controller_ && IsShadowModal(context_)) {
42         controller_ = CREATE_ANIMATOR(GetContext());
43         controller_->SetFillMode(FillMode::FORWARDS);
44     }
45     auto root = AceType::DynamicCast<RootComponent>(component);
46     if (root) {
47         isContextMenu_ = root->IsContextMenu();
48     }
49     MarkNeedLayout();
50 }
51 
PerformLayout()52 void RenderRoot::PerformLayout()
53 {
54     auto appTheme = GetTheme<AppTheme>();
55     // Use theme background color to clear canvas.
56     if (appTheme && !isBgColorInit_) {
57         if (IsShadowModal(context_)) {
58             bgColor_ = appTheme->GetBackgroundColor();
59             auto colorAnimation =
60                 AceType::MakeRefPtr<CurveAnimation<Color>>(Color::TRANSPARENT, bgColor_, Curves::FAST_OUT_SLOW_IN);
61             bgColor_ = Color::TRANSPARENT;
62             colorAnimation->AddListener([weak = AceType::WeakClaim(this)](const Color& color) {
63                 auto root = weak.Upgrade();
64                 if (!root) {
65                     LOGE("Root transition failed. root is null.");
66                     return;
67                 }
68                 if (!root->forceColor_) {
69                     root->bgColor_ = color;
70                     root->MarkNeedRender();
71                 }
72             });
73             controller_->AddInterpolator(colorAnimation);
74         }
75         if (isContextMenu_) {
76             bgColor_ = Color::TRANSPARENT;
77         }
78         isBgColorInit_ = true;
79     }
80     viewPort_ = GetPaintRect().GetSize();
81     LayoutParam innerLayoutParam;
82     innerLayoutParam.SetMaxSize(GetPaintRect().GetSize());
83 
84     for (auto& child : GetChildren()) {
85         child->Layout(innerLayoutParam);
86         child->SetPosition(Offset::Zero());
87     }
88 }
89 
DumpLayerTree()90 void RenderRoot::DumpLayerTree() {}
91 
AnimateToHide(int32_t duration)92 void RenderRoot::AnimateToHide(int32_t duration)
93 {
94     if (controller_) {
95         controller_->SetDuration(duration);
96         controller_->Backward();
97     }
98 }
99 
AnimateToShow(int32_t duration)100 void RenderRoot::AnimateToShow(int32_t duration)
101 {
102     if (controller_) {
103         controller_->SetDuration(duration);
104         controller_->Forward();
105     }
106 }
107 
SetDefaultBgColor(bool isTransparent)108 void RenderRoot::SetDefaultBgColor(bool isTransparent)
109 {
110     auto appTheme = GetTheme<AppTheme>();
111     if (!appTheme) {
112         return;
113     }
114     bgColor_ = isContextMenu_ || isTransparent ? Color::TRANSPARENT : appTheme->GetBackgroundColor();
115     forceColor_ = false;
116     MarkNeedRender();
117 }
118 
SetBgColor(const Color & color)119 void RenderRoot::SetBgColor(const Color& color)
120 {
121     bgColor_ = isContextMenu_ ? Color::TRANSPARENT : color;
122     forceColor_ = true;
123     MarkNeedRender();
124 }
125 
GetBgColor() const126 Color RenderRoot::GetBgColor() const
127 {
128     return isContextMenu_ ? Color::TRANSPARENT : bgColor_;
129 }
130 } // namespace OHOS::Ace
131