• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/display/render_display.h"
17 
18 #include "base/log/dump_log.h"
19 #include "base/log/event_report.h"
20 #include "core/animation/curve_animation.h"
21 
22 namespace OHOS::Ace {
23 
Update(const RefPtr<Component> & component)24 void RenderDisplay::Update(const RefPtr<Component>& component)
25 {
26     const RefPtr<DisplayComponent> display = AceType::DynamicCast<DisplayComponent>(component);
27     if (!display) {
28         LOGE("RenderDisplay update with nullptr");
29         EventReport::SendRenderException(RenderExcepType::RENDER_COMPONENT_ERR);
30         return;
31     }
32     displayComponent_ = display;
33     bool needAppearingCard = false;
34     if ((visible_ == VisibleType::GONE) && (display->GetVisible() != VisibleType::GONE)) {
35         needAppearingCard = true;
36     }
37     UpdateVisibleType(display->GetVisible());
38     duration_ = display->GetAppearingDuration();
39     transitionOpacity_ = display->GetOpacity();
40     disappearingOpacity_ = display->GetDisappearingOpacity();
41     appearingOpacity_ = display->GetAppearingOpacity();
42     hasDisappearTransition_ = display->HasDisappearTransition();
43     hasAppearTransition_ = display->HasAppearTransition();
44     if (!hasDisappearTransition_) {
45         pendingAppearing_ = false;
46     }
47     if (!pendingAppearing_) {
48         animatableOpacity_ = AnimatableDouble(display->GetOpacity(), display->GetOpacityAnimationOption());
49     }
50     double opacity = std::min(std::max(animatableOpacity_.GetValue(), 0.0), 1.0);
51     if (disableLayer_ != display->IsDisableLayer()) {
52         // recover opacity in child
53         UpdateOpacity(UINT8_MAX);
54         disableLayer_ = display->IsDisableLayer();
55     }
56     opacity_ = static_cast<uint8_t>(round(opacity * UINT8_MAX));
57     auto limitDuration = GetCardAppearingDuration();
58     if (duration_ > 0 && limitDuration > 0 && needAppearingCard) {
59         CreateAppearingAnimation(opacity_, limitDuration);
60         opacity_ = 0;
61         animator_->Play();
62     }
63 
64     if (display->HasStateAttributes()) {
65         stateAttributeList_ = display->GetStateAttributes();
66     }
67     OnStatusStyleChanged(VisualState::NORMAL);
68     SetShadow(display->GetShadow());
69     MarkNeedLayout();
70 }
71 
PerformLayout()72 void RenderDisplay::PerformLayout()
73 {
74     if (pendingAppearing_) {
75         if (animatableOpacity_.GetAnimationStatus() != Animator::Status::RUNNING) {
76             animatableOpacity_.MoveTo(appearingOpacity_);
77         }
78         // appearing transition do not need stop callback anymore.
79         animatableOpacity_.SetAnimationStopCallback(nullptr);
80         animatableOpacity_ = AnimatableDouble(opacity_ / (1.0 * UINT8_MAX));
81         pendingAppearing_ = false;
82     }
83     LayoutParam layoutParam = GetLayoutParam();
84     if (visible_ == VisibleType::GONE) {
85         layoutParam.SetMinSize(Size());
86         layoutParam.SetMaxSize(Size());
87         SetVisible(false);
88     }
89     Size childSize;
90     if (!GetChildren().empty()) {
91         const auto& child = GetChildren().front();
92         child->Layout(layoutParam);
93         childSize = child->GetLayoutSize();
94         child->SetPosition(Offset());
95     }
96     SetLayoutSize(childSize);
97 }
98 
GetOpacityCallbacks()99 void RenderDisplay::GetOpacityCallbacks()
100 {
101     opacityCallbacks_.clear();
102     if (!disableLayer_) {
103         return;
104     }
105     GetDomOpacityCallbacks(GetNodeId(), opacityCallbacks_);
106 }
107 
Dump()108 void RenderDisplay::Dump()
109 {
110     DumpLog::GetInstance().AddDesc(
111         std::string("Display: ")
112             .append(visible_ == VisibleType::VISIBLE ? "visible"
113                                                         : visible_ == VisibleType::INVISIBLE ? "invisible" : "gone"));
114     DumpLog::GetInstance().AddDesc(std::string("Opacity: ").append(std::to_string(animatableOpacity_.GetValue())));
115 }
116 
GetVisible() const117 bool RenderDisplay::GetVisible() const
118 {
119     return RenderNode::GetVisible() && (visible_ == VisibleType::VISIBLE);
120 }
121 
OnOpacityDisappearingCallback()122 void RenderDisplay::OnOpacityDisappearingCallback()
123 {
124     LOGD("OnOpacityDisappearingCallback");
125     RefPtr<RenderNode> child = AceType::Claim(this);
126     while (child && !child->IsDisappearing()) {
127         child = child->GetParent().Upgrade();
128     }
129     if (!child) {
130         return;
131     }
132     auto parent = child->GetParent().Upgrade();
133     if (parent) {
134         parent->ClearDisappearingNode(child);
135     }
136 }
137 
OnOpacityAnimationCallback()138 void RenderDisplay::OnOpacityAnimationCallback()
139 {
140     double value = animatableOpacity_.GetValue();
141     opacity_ = static_cast<uint8_t>(round(value * UINT8_MAX));
142     MarkNeedRender();
143     if (disableLayer_) {
144         UpdateOpacity(opacity_);
145     }
146 }
147 
HasDisappearingTransition(int32_t nodeId)148 bool RenderDisplay::HasDisappearingTransition(int32_t nodeId)
149 {
150     return hasDisappearTransition_ || RenderNode::HasDisappearingTransition(nodeId);
151 }
152 
OnTransition(TransitionType type,int32_t id)153 void RenderDisplay::OnTransition(TransitionType type, int32_t id)
154 {
155     LOGD("OnTransition. type: %{public}d, id: %{public}d", type, id);
156     if (type == TransitionType::APPEARING) {
157         pendingAppearing_ = true;
158         MarkNeedLayout();
159     } else if (type == TransitionType::DISAPPEARING) {
160         animatableOpacity_.SetAnimationStopCallback(std::bind(&RenderDisplay::OnOpacityDisappearingCallback, this));
161         animatableOpacity_ = AnimatableDouble(disappearingOpacity_);
162     }
163 }
164 
ClearRenderObject()165 void RenderDisplay::ClearRenderObject()
166 {
167     RenderNode::ClearRenderObject();
168     animatableOpacity_ = 1.0;
169     appearingOpacity_ = 0.0;
170     disappearingOpacity_ = 0.0;
171 }
172 
GetCardAppearingDuration()173 int32_t RenderDisplay::GetCardAppearingDuration()
174 {
175     auto pipeline = context_.Upgrade();
176     if (!pipeline) {
177         LOGE("pipeline context is nullptr");
178         return 0;
179     }
180     auto limitDuration = pipeline->GetAppearingDuration();
181     return limitDuration;
182 }
183 
ResetAppearingAnimation()184 void RenderDisplay::ResetAppearingAnimation()
185 {
186     if (animator_->GetStatus() != Animator::Status::STOPPED) {
187         animator_->Stop();
188     }
189     animator_->ClearInterpolators();
190 }
191 
CreateAppearingAnimation(uint8_t opacity,int32_t limit)192 void RenderDisplay::CreateAppearingAnimation(uint8_t opacity, int32_t limit)
193 {
194     if (!animator_) {
195         animator_ = AceType::MakeRefPtr<Animator>(context_);
196     }
197     ResetAppearingAnimation();
198     if (!appearingAnimation_) {
199         appearingAnimation_ = AceType::MakeRefPtr<CurveAnimation<uint8_t>>(0, opacity, Curves::FRICTION);
200     }
201     appearingAnimation_->AddListener([weak = WeakClaim(this)](const uint8_t value) {
202         auto display = weak.Upgrade();
203         if (display) {
204             display->UpdateOpacity(value);
205         }
206     });
207     animator_->AddInterpolator(appearingAnimation_);
208     animator_->SetDuration(std::min(duration_, limit));
209 }
210 
OnStatusStyleChanged(VisualState componentState)211 void RenderDisplay::OnStatusStyleChanged(VisualState componentState)
212 {
213     RenderNode::OnStatusStyleChanged(componentState);
214     if (stateAttributeList_ == nullptr) {
215         return;
216     }
217 
218     bool updated = false;
219     for (auto& attribute : stateAttributeList_->GetAttributesForState(componentState)) {
220         updated = true;
221         switch (attribute->id_) {
222             case DisplayStateAttribute::OPACITY: {
223                 auto opacityState =
224                     AceType::DynamicCast<StateAttributeValue<DisplayStateAttribute, AnimatableDouble>>(attribute);
225                 if (!pendingAppearing_) {
226                     animatableOpacity_ = opacityState->value_;
227                 }
228                 opacity_ = static_cast<uint8_t>(round(animatableOpacity_.GetValue() * UINT8_MAX));
229             } break;
230         }
231     }
232     if (updated) {
233         MarkNeedLayout();
234     }
235 }
236 
237 } // namespace OHOS::Ace
238