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/semi_modal/semi_modal_element.h"
17
18 #include "core/components/box/box_element.h"
19 #include "core/components/flex/flex_element.h"
20 #include "core/components/flex/flex_item_element.h"
21 #include "core/components/semi_modal/render_semi_modal.h"
22
23 namespace OHOS::Ace {
24 namespace {
25
26 const auto BACKGROUND_COLOR_DEFAULT = Color::WHITE;
27 constexpr uint32_t COLUMN_CHILD_MIN = 2;
28
29 } // namespace
30
AnimateToFullWindow(int32_t duration)31 void SemiModalElement::AnimateToFullWindow(int32_t duration)
32 {
33 auto render = AceType::DynamicCast<RenderSemiModal>(GetRenderNode());
34 if (!render) {
35 LOGE("Animate full window failed. render is null");
36 return;
37 }
38 render->AnimateToFullWindow(duration);
39 }
40
GetBackgroundColor() const41 const Color& SemiModalElement::GetBackgroundColor() const
42 {
43 auto boxElement = GetFirstChild();
44 if (!boxElement) {
45 LOGE("Get background color failed. box element is null");
46 return BACKGROUND_COLOR_DEFAULT;
47 }
48 auto boxRender = AceType::DynamicCast<RenderBox>(boxElement->GetRenderNode());
49 if (!boxRender) {
50 LOGE("Get background color failed. box render is null");
51 return BACKGROUND_COLOR_DEFAULT;
52 }
53 auto decoration = boxRender->GetBackDecoration();
54 if (!decoration) {
55 LOGE("Get background color failed. box decoration is null");
56 return BACKGROUND_COLOR_DEFAULT;
57 }
58 return decoration->GetBackgroundColor();
59 }
60
IsFullWindow() const61 bool SemiModalElement::IsFullWindow() const
62 {
63 return fullWindow_;
64 }
65
SetFullWindow(bool fullWindow)66 void SemiModalElement::SetFullWindow(bool fullWindow)
67 {
68 fullWindow_ = fullWindow;
69 }
70
UpdateSystemBarHeight(double statusBar,double navigationBar)71 void SemiModalElement::UpdateSystemBarHeight(double statusBar, double navigationBar)
72 {
73 auto box = GetFirstChild();
74 if (!box) {
75 LOGE("Update system bar failed. box is null.");
76 return;
77 }
78 auto column = box->GetFirstChild();
79 UpdateStatusBarHeight(column, statusBar);
80 UpdateNavigationBarHeight(column, navigationBar);
81 }
82
UpdateStatusBarHeight(const RefPtr<Element> & column,double height)83 void SemiModalElement::UpdateStatusBarHeight(const RefPtr<Element>& column, double height)
84 {
85 auto renderSemi = AceType::DynamicCast<RenderSemiModal>(GetRenderNode());
86 if (!renderSemi) {
87 LOGE("Update status bar failed. RenderSemi is null.");
88 return;
89 }
90 renderSemi->OnStatusBarHeightChanged(Dimension(height, DimensionUnit::VP));
91 if (!column) {
92 LOGE("Update status bar failed. column is null.");
93 return;
94 }
95 auto dragBarElement = column->GetFirstChild();
96 if (!dragBarElement) {
97 LOGE("Update status bar failed. drag bar element is null.");
98 return;
99 }
100 auto dragBarRender = AceType::DynamicCast<RenderDragBar>(dragBarElement->GetRenderNode());
101 if (!dragBarRender) {
102 LOGE("Update status bar failed. drag bar render is null.");
103 return;
104 }
105 dragBarRender->SetStatusBarHeight(height);
106 }
107
UpdateNavigationBarHeight(const RefPtr<Element> & column,double height)108 void SemiModalElement::UpdateNavigationBarHeight(const RefPtr<Element>& column, double height)
109 {
110 auto renderSemi = AceType::DynamicCast<RenderSemiModal>(GetRenderNode());
111 if (!renderSemi) {
112 LOGE("Update navigation bar failed. RenderSemi is null.");
113 return;
114 }
115 renderSemi->OnNavigationBarHeightChanged(Dimension(height, DimensionUnit::VP));
116 if (!column) {
117 LOGE("Update navigation bar failed. column is null.");
118 return;
119 }
120 auto navigationElement = column->GetLastChild();
121 if (!navigationElement) {
122 LOGE("Update navigation bar failed. navigation element is null.");
123 return;
124 }
125 auto navigationRender = AceType::DynamicCast<RenderBoxBase>(navigationElement->GetRenderNode());
126 if (!navigationRender) {
127 LOGE("Update navigation bar failed. navigation render is null.");
128 return;
129 }
130 auto context = context_.Upgrade();
131 if (!context) {
132 LOGE("Update navigation bar failed. context is null.");
133 return;
134 }
135 navigationRender->SetHeight(context->NormalizeToPx(Dimension(height, DimensionUnit::VP)));
136 }
137
GetOverlayElement() const138 RefPtr<OverlayElement> SemiModalElement::GetOverlayElement() const
139 {
140 auto box = AceType::DynamicCast<BoxElement>(GetFirstChild());
141 if (!box) {
142 LOGE("Get overlay element failed. Box element is null!");
143 return RefPtr<OverlayElement>();
144 }
145 auto column = AceType::DynamicCast<ColumnElement>(box->GetFirstChild());
146 if (!column || column->GetChildren().size() < COLUMN_CHILD_MIN) {
147 // column should has more than 2 child
148 LOGE("Get overlay element failed. Column is null or child size error!");
149 return RefPtr<OverlayElement>();
150 }
151 // Get second child
152 auto secondItr = std::next(column->GetChildren().begin());
153 auto flexItem = AceType::DynamicCast<FlexItemElement>(*secondItr);
154 if (!flexItem) {
155 LOGE("Get overlay element failed. FlexItemElement is null!");
156 return RefPtr<OverlayElement>();
157 }
158 auto clip = flexItem->GetFirstChild();
159 if (!clip) {
160 LOGE("Get overlay element failed. clip is null!");
161 return RefPtr<OverlayElement>();
162 }
163 auto stack = clip->GetFirstChild();
164 if (!stack) {
165 return RefPtr<OverlayElement>();
166 }
167 auto child = stack->GetChildren();
168 if (child.size() > 1) {
169 auto it = child.begin();
170 it++;
171 return AceType::DynamicCast<OverlayElement>(*it);
172 }
173 return RefPtr<OverlayElement>();
174 }
175
GetStageElement() const176 RefPtr<StageElement> SemiModalElement::GetStageElement() const
177 {
178 auto box = AceType::DynamicCast<BoxElement>(GetFirstChild());
179 if (!box) {
180 LOGE("Get stage element failed. Box element is null!");
181 return RefPtr<StageElement>();
182 }
183 auto column = AceType::DynamicCast<ColumnElement>(box->GetFirstChild());
184 if (!column || column->GetChildren().size() < COLUMN_CHILD_MIN) {
185 // column should has more than 2 child
186 LOGE("Get stage element failed. Column is null or child size error!");
187 return RefPtr<StageElement>();
188 }
189 // Get second child
190 auto secondItr = std::next(column->GetChildren().begin());
191 auto flexItem = AceType::DynamicCast<FlexItemElement>(*secondItr);
192 if (!flexItem) {
193 LOGE("Get stage element failed. FlexItemElement is null!");
194 return RefPtr<StageElement>();
195 }
196 auto clip = flexItem->GetFirstChild();
197 if (!clip) {
198 LOGE("Get stage element failed. clip is null!");
199 return RefPtr<StageElement>();
200 }
201 auto stack = clip->GetFirstChild();
202 if (!stack) {
203 return RefPtr<StageElement>();
204 }
205 return AceType::DynamicCast<StageElement>(stack->GetFirstChild());
206 }
207
AnimateToExitApp() const208 void SemiModalElement::AnimateToExitApp() const
209 {
210 auto renderSemi = AceType::DynamicCast<RenderSemiModal>(GetRenderNode());
211 if (!renderSemi) {
212 LOGE("Animate To Exit failed. RenderSemi is null.");
213 return;
214 }
215 renderSemi->AnimateToExitApp();
216 }
217
218 } // namespace OHOS::Ace