1 /*
2 * Copyright (c) 2021-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/navigator/render_navigator.h"
17
18 #include "base/log/event_report.h"
19 #include "core/components/page/page_target.h"
20
21 namespace OHOS::Ace {
22
RenderNavigator()23 RenderNavigator::RenderNavigator()
24 {
25 Initialize();
26 }
27
Create()28 RefPtr<RenderNode> RenderNavigator::Create()
29 {
30 return AceType::MakeRefPtr<RenderNavigator>();
31 }
32
Initialize()33 void RenderNavigator::Initialize()
34 {
35 auto wp = AceType::WeakClaim(this);
36 clickRecognizer_ = AceType::MakeRefPtr<ClickRecognizer>();
37 clickRecognizer_->SetOnClick([wp](const ClickInfo& info) {
38 LOGI("navigator OnClick called");
39 auto navigator = wp.Upgrade();
40 if (!navigator) {
41 return;
42 }
43 const auto context = navigator->GetContext().Upgrade();
44 if (context && context->GetIsDeclarative()) {
45 navigator->HandleClickEvent(info);
46 } else {
47 navigator->HandleClickEvent();
48 }
49 navigator->NavigatePage();
50 });
51 }
52
HandleClickEvent(const ClickInfo & info)53 void RenderNavigator::HandleClickEvent(const ClickInfo& info)
54 {
55 if (onClickWithInfo_) {
56 onClickWithInfo_(info);
57 }
58 }
59
HandleClickEvent()60 void RenderNavigator::HandleClickEvent()
61 {
62 if (onClick_) {
63 onClick_();
64 }
65 }
66
NavigatePage()67 void RenderNavigator::NavigatePage()
68 {
69 auto pipelineContext = GetContext().Upgrade();
70 if (!pipelineContext) {
71 LOGE("pipelineContext is null");
72 return;
73 }
74
75 pipelineContext->NavigatePage(
76 static_cast<uint8_t>(type_), PageTarget(uri_, targetContainer_, useSubStage_), params_);
77 }
78
Update(const RefPtr<Component> & component)79 void RenderNavigator::Update(const RefPtr<Component>& component)
80 {
81 const RefPtr<NavigatorComponent> navigator = AceType::DynamicCast<NavigatorComponent>(component);
82 if (!navigator) {
83 LOGE("Update error, navigator component is null");
84 EventReport::SendRenderException(RenderExcepType::RENDER_COMPONENT_ERR);
85 return;
86 }
87
88 uri_ = navigator->GetUri();
89 params_ = navigator->GetParams();
90 type_ = navigator->GetType();
91 active_ = navigator->GetActive();
92 isDefHeight_ = navigator->IsDefHeight();
93 isDefWidth_ = navigator->IsDefWidth();
94 onClickWithInfo_ = AceAsyncEvent<void(const ClickInfo&)>::Create(navigator->GetClickedEventId(), context_);
95 onClick_ = AceAsyncEvent<void()>::Create(navigator->GetClickedEventId(), context_);
96 LOGI("navigator Update uri = %{public}s type = %{public}d", uri_.c_str(), type_);
97
98 if (active_ == true) {
99 NavigatePage();
100 }
101 SetAccessibilityClickImpl();
102 MarkNeedLayout();
103 }
104
PerformLayout()105 void RenderNavigator::PerformLayout()
106 {
107 if (!GetChildren().empty()) {
108 LayoutParam innerLayout = GetLayoutParam();
109 auto child = GetChildren().front();
110 child->Layout(innerLayout);
111 Size maxSize = innerLayout.GetMaxSize();
112 double maxWidth = maxSize.Width();
113 double maxHeight = maxSize.Height();
114 if (!isDefHeight_) {
115 maxHeight = child->GetLayoutSize().Height();
116 }
117 if (!isDefWidth_) {
118 maxWidth = child->GetLayoutSize().Width();
119 }
120 SetLayoutSize(Size(maxWidth, maxHeight));
121 child->SetPosition(Alignment::GetAlignPosition(GetLayoutSize(), child->GetLayoutSize(), Alignment::CENTER));
122 } else {
123 SetLayoutSize(GetLayoutParam().GetMaxSize());
124 }
125 }
126
OnTouchTestHit(const Offset & coordinateOffset,const TouchRestrict & touchRestrict,TouchTestResult & result)127 void RenderNavigator::OnTouchTestHit(
128 const Offset& coordinateOffset, const TouchRestrict& touchRestrict, TouchTestResult& result)
129 {
130 if (!clickRecognizer_) {
131 return;
132 }
133 clickRecognizer_->SetCoordinateOffset(coordinateOffset);
134 result.emplace_back(clickRecognizer_);
135 }
136
SetAccessibilityClickImpl()137 void RenderNavigator::SetAccessibilityClickImpl()
138 {
139 auto accessibilityNode = accessibilityNode_.Upgrade();
140 if (accessibilityNode) {
141 auto weakPtr = AceType::WeakClaim(AceType::RawPtr(clickRecognizer_));
142 accessibilityNode->AddSupportAction(AceAction::ACTION_CLICK);
143 accessibilityNode->SetClickableState(true);
144 accessibilityNode->SetActionClickImpl([weakPtr]() {
145 auto click = weakPtr.Upgrade();
146 if (click) {
147 click->OnAccepted();
148 }
149 });
150 }
151 }
152
153 } // namespace OHOS::Ace
154