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