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_ng/manager/full_screen/full_screen_manager.h"
17
18 #include "base/utils/utils.h"
19 #include "core/components_ng/base/geometry_node.h"
20 #include "core/components_ng/pattern/video/video_pattern.h"
21 #include "core/components_v2/inspector/inspector_constants.h"
22 #include "core/pipeline_ng/pipeline_context.h"
23
24 namespace OHOS::Ace::NG {
25
RequestFullScreen(const RefPtr<FrameNode> & frameNode)26 void FullScreenManager::RequestFullScreen(const RefPtr<FrameNode>& frameNode)
27 {
28 auto rootNode = rootNodeWeak_.Upgrade();
29 CHECK_NULL_VOID(rootNode);
30 auto parentNode = frameNode->GetParent();
31 auto nodeId = frameNode->GetId();
32 if (originalParent_.count(nodeId) > 0) {
33 LOGE("FrameNode has existed");
34 return;
35 }
36 frameNode->MountToParent(rootNode);
37 auto slot = parentNode->RemoveChildAndReturnIndex(frameNode);
38 auto resultForParent = originalParent_.try_emplace(nodeId, parentNode, slot);
39 if (!resultForParent.second) {
40 return;
41 }
42 auto geometryNode = frameNode->GetGeometryNode();
43 auto originGeometryNode = geometryNode->Clone();
44 auto resultForGeo = originGeometryNode_.try_emplace(nodeId, originGeometryNode);
45 if (!resultForGeo.second) {
46 return;
47 }
48 // TODO: remove the original property of padding&margin
49 auto rootWidth = PipelineContext::GetCurrentRootWidth();
50 auto rootHeight = PipelineContext::GetCurrentRootHeight();
51 auto calcRootWidth = CalcLength(rootWidth);
52 auto calcRootHeight = CalcLength(rootHeight);
53 LayoutConstraintF parentLayoutConstraint;
54 parentLayoutConstraint.maxSize.SetWidth(static_cast<float>(rootWidth));
55 parentLayoutConstraint.maxSize.SetHeight(static_cast<float>(rootHeight));
56 geometryNode->SetParentLayoutConstraint(parentLayoutConstraint);
57 frameNode->GetGeometryNode()->SetMarginFrameOffset(OffsetF { 0.0f, 0.0f });
58 frameNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
59 rootNode->RebuildRenderContextTree();
60 rootNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
61 }
62
ExitFullScreen(const RefPtr<FrameNode> & frameNode)63 void FullScreenManager::ExitFullScreen(const RefPtr<FrameNode>& frameNode)
64 {
65 auto nodeId = frameNode->GetId();
66 auto iterOfParent = originalParent_.find(nodeId);
67 auto iterOfGeometryNode = originGeometryNode_.find(nodeId);
68 if (iterOfParent == originalParent_.end() || iterOfGeometryNode == originGeometryNode_.end()) {
69 LOGE("FrameNode not find!");
70 return;
71 }
72 auto rootNode = rootNodeWeak_.Upgrade();
73 CHECK_NULL_VOID(rootNode);
74 rootNode->RemoveChild(frameNode);
75 rootNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
76
77 auto parent = iterOfParent->second.first.Upgrade();
78 CHECK_NULL_VOID(parent);
79 auto slot = iterOfParent->second.second;
80
81 // TODO: recover the original property of padding&margin
82 auto originGeometryNode = iterOfGeometryNode->second;
83 auto originFrameOffset = originGeometryNode->GetMarginFrameOffset();
84 auto originParentGlobalOffset = originGeometryNode->GetParentGlobalOffset();
85 frameNode->GetGeometryNode()->SetMarginFrameOffset(originFrameOffset);
86 frameNode->GetGeometryNode()->SetParentGlobalOffset(originParentGlobalOffset);
87 originalParent_.erase(iterOfParent);
88 originGeometryNode_.erase(iterOfGeometryNode);
89 // TODO: need to reserve the value set by developers
90 frameNode->MountToParent(parent, slot);
91 frameNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
92 parent->MarkDirtyNode(PROPERTY_UPDATE_LAYOUT);
93 parent->RebuildRenderContextTree();
94 }
95
RequestFullScreenForWeb(const RefPtr<FrameNode> & frameNode)96 void FullScreenManager::RequestFullScreenForWeb(const RefPtr<FrameNode>& frameNode)
97 {
98 auto rootNode = rootNodeWeak_.Upgrade();
99 CHECK_NULL_VOID(rootNode);
100 auto parentNode = frameNode->GetParent();
101 auto nodeId = frameNode->GetId();
102 if (originalParent_.count(nodeId) > 0) {
103 LOGE("FrameNode has existed");
104 return;
105 }
106 frameNode->MountToParent(rootNode);
107 auto slot = parentNode->RemoveChildAndReturnIndex(frameNode);
108 auto resultForParent = originalParent_.try_emplace(nodeId, parentNode, slot);
109 if (!resultForParent.second) {
110 return;
111 }
112 auto geometryNode = frameNode->GetGeometryNode();
113 auto originGeometryNode = geometryNode->Clone();
114 auto resultForGeo = originGeometryNode_.try_emplace(nodeId, originGeometryNode);
115 if (!resultForGeo.second) {
116 return;
117 }
118 // TODO: remove the original property of padding&margin
119 auto rootWidth = PipelineContext::GetCurrentRootWidth();
120 auto rootHeight = PipelineContext::GetCurrentRootHeight();
121 auto calcRootWidth = CalcLength(rootWidth);
122 auto calcRootHeight = CalcLength(rootHeight);
123 CalcSize idealSize = { calcRootWidth, calcRootHeight };
124 MeasureProperty layoutConstraint;
125 layoutConstraint.selfIdealSize = idealSize;
126 layoutConstraint.maxSize = idealSize;
127 LayoutConstraintF parentLayoutConstraint;
128 parentLayoutConstraint.maxSize.SetWidth(static_cast<float>(rootWidth));
129 parentLayoutConstraint.maxSize.SetHeight(static_cast<float>(rootHeight));
130 geometryNode->SetParentLayoutConstraint(parentLayoutConstraint);
131 frameNode->UpdateLayoutConstraint(layoutConstraint);
132 frameNode->GetGeometryNode()->SetMarginFrameOffset(OffsetF { 0.0f, 0.0f });
133 frameNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
134 rootNode->RebuildRenderContextTree();
135 rootNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
136 }
137
ExitFullScreenForWeb(const RefPtr<FrameNode> & frameNode)138 void FullScreenManager::ExitFullScreenForWeb(const RefPtr<FrameNode>& frameNode)
139 {
140 auto nodeId = frameNode->GetId();
141 auto iterOfParent = originalParent_.find(nodeId);
142 auto iterOfGeometryNode = originGeometryNode_.find(nodeId);
143 if (iterOfParent == originalParent_.end() || iterOfGeometryNode == originGeometryNode_.end()) {
144 LOGE("FrameNode not find!");
145 return;
146 }
147 auto rootNode = rootNodeWeak_.Upgrade();
148 CHECK_NULL_VOID(rootNode);
149 rootNode->RemoveChild(frameNode);
150 rootNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
151
152 auto parent = iterOfParent->second.first.Upgrade();
153 CHECK_NULL_VOID(parent);
154 auto slot = iterOfParent->second.second;
155
156 // TODO: recover the original property of padding&margin
157 auto originGeometryNode = iterOfGeometryNode->second;
158 auto originFrameOffset = originGeometryNode->GetMarginFrameOffset();
159 auto originParentGlobalOffset = originGeometryNode->GetParentGlobalOffset();
160 frameNode->GetGeometryNode()->SetMarginFrameOffset(originFrameOffset);
161 frameNode->GetGeometryNode()->SetParentGlobalOffset(originParentGlobalOffset);
162 MeasureProperty layoutConstraint;
163 auto geoFrameSize = originGeometryNode->GetFrameSize();
164 CalcSize idealSize;
165 idealSize = { CalcLength(geoFrameSize.Width()), CalcLength(geoFrameSize.Height()) };
166 layoutConstraint.selfIdealSize = idealSize;
167
168 originalParent_.erase(iterOfParent);
169 originGeometryNode_.erase(iterOfGeometryNode);
170 // TODO: need to reserve the value set by developers
171 frameNode->UpdateLayoutConstraint(layoutConstraint);
172 frameNode->MountToParent(parent, slot);
173 frameNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
174 parent->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
175 parent->RebuildRenderContextTree();
176 }
177
OnBackPressed()178 bool FullScreenManager::OnBackPressed()
179 {
180 auto rootNode = rootNodeWeak_.Upgrade();
181 CHECK_NULL_RETURN(rootNode, false);
182 auto child = rootNode->GetLastChild();
183 auto frameNode = AceType::DynamicCast<FrameNode>(child);
184 CHECK_NULL_RETURN(frameNode, false);
185 if (frameNode->GetTag() != V2::VIDEO_ETS_TAG) {
186 return false;
187 }
188
189 auto pattern = frameNode->GetPattern();
190 CHECK_NULL_RETURN(pattern, false);
191 auto videoPattern = AceType::DynamicCast<VideoPattern>(pattern);
192 CHECK_NULL_RETURN(videoPattern, false);
193 return videoPattern->OnBackPressed();
194 }
195
196 } // namespace OHOS::Ace::NG
197