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/hyperlink/render_hyperlink.h"
17
18 #include "core/components/image/image_component.h"
19 #include "core/components/text/text_component.h"
20 #include "core/pipeline/base/multi_composed_component.h"
21
22 namespace OHOS::Ace {
23
RenderHyperlink()24 RenderHyperlink::RenderHyperlink()
25 {
26 Initialize();
27 }
28
Create()29 RefPtr<RenderNode> RenderHyperlink::Create()
30 {
31 return AceType::MakeRefPtr<RenderHyperlink>();
32 }
33
Initialize()34 void RenderHyperlink::Initialize()
35 {
36 auto wp = AceType::WeakClaim(this);
37 clickRecognizer_ = AceType::MakeRefPtr<ClickRecognizer>();
38 clickRecognizer_->SetOnClick([wp](const ClickInfo& info) {
39 auto hyperlink = wp.Upgrade();
40 if (!hyperlink) {
41 return;
42 }
43 hyperlink->JumpToAddress();
44 });
45 }
46
Update(const RefPtr<Component> & component)47 void RenderHyperlink::Update(const RefPtr<Component>& component)
48 {
49 hyperlinkComponent_ = AceType::DynamicCast<HyperlinkComponent>(component);
50 if (!hyperlinkComponent_) {
51 LOGE("update error, hyperlink is null.");
52 return;
53 }
54 address_ = hyperlinkComponent_->GetAddress();
55 color_ = hyperlinkComponent_->GetColor();
56 SetImageChildColor(hyperlinkComponent_);
57 if (!hyperlinkResources_) {
58 hyperlinkResources_ = AceType::MakeRefPtr<HyperlinkResources>(context_);
59 hyperlinkResources_->CreatePlatformResource(context_);
60 }
61 MarkNeedLayout();
62 }
63
PerformLayout()64 void RenderHyperlink::PerformLayout()
65 {
66 if (!GetChildren().empty()) {
67 const auto& child = GetChildren().front();
68 child->Layout(GetLayoutParam());
69 auto childSize = child->GetLayoutSize();
70 SetLayoutSize(childSize);
71 }
72 }
73
OnTouchTestHit(const Offset & coordinateOffset,const TouchRestrict & touchRestrict,TouchTestResult & result)74 void RenderHyperlink::OnTouchTestHit(
75 const Offset& coordinateOffset, const TouchRestrict& touchRestrict, TouchTestResult& result)
76 {
77 if (!clickRecognizer_) {
78 return;
79 }
80 clickRecognizer_->SetCoordinateOffset(coordinateOffset);
81 result.emplace_back(clickRecognizer_);
82 }
83
JumpToAddress()84 void RenderHyperlink::JumpToAddress()
85 {
86 #if defined(PREVIEW)
87 LOGW("[Engine Log] Unable to use the Hyperlink in the Previewer. "
88 "Perform this operation on the emulator or a real device instead.");
89 return;
90 #endif
91 auto context = context_.Upgrade();
92 if (context) {
93 context->HyperlinkStartAbility(address_);
94 }
95 }
96
SetImageChildColor(const RefPtr<Component> node)97 void RenderHyperlink::SetImageChildColor(const RefPtr<Component> node)
98 {
99 if (node == nullptr) {
100 return;
101 }
102 auto componentGroup = AceType::DynamicCast<ComponentGroup>(node);
103 auto multiComposedComponent = AceType::DynamicCast<MultiComposedComponent>(node);
104 auto composedComponent = AceType::DynamicCast<ComposedComponent>(node);
105 auto singleChildComponent = AceType::DynamicCast<SoleChildComponent>(node);
106 auto imageComponent = AceType::DynamicCast<ImageComponent>(node);
107 auto textComponent = AceType::DynamicCast<TextComponent>(node);
108 if (imageComponent) {
109 imageComponent->SetImageFill(GetColor());
110 return;
111 }
112 if (textComponent) {
113 auto textStyle = textComponent->GetTextStyle();
114 textStyle.SetTextColor(GetColor());
115 textComponent->SetTextStyle(std::move(textStyle));
116 return;
117 }
118 if (componentGroup) {
119 std::list<RefPtr<Component>> children = componentGroup->GetChildren();
120 for (const auto& child : children) {
121 SetImageChildColor(child);
122 }
123 } else if (multiComposedComponent) {
124 std::list<RefPtr<Component>> children = multiComposedComponent->GetChildren();
125 for (const auto& child : children) {
126 SetImageChildColor(child);
127 }
128 } else if (composedComponent) {
129 auto child = composedComponent->GetChild();
130 SetImageChildColor(child);
131 } else if (singleChildComponent) {
132 auto child = singleChildComponent->GetChild();
133 SetImageChildColor(child);
134 }
135 }
136
HandleMouseEvent(const MouseEvent & event)137 bool RenderHyperlink::HandleMouseEvent(const MouseEvent& event)
138 {
139 return true;
140 }
141
HandleMouseHoverEvent(MouseState mouseState)142 void RenderHyperlink::HandleMouseHoverEvent(MouseState mouseState)
143 {
144 auto mousestyle = MouseStyle::CreateMouseStyle();
145 auto pipeline = context_.Upgrade();
146 if (!pipeline) {
147 return;
148 }
149 uint32_t windowId = pipeline->GetWindowId();
150 MouseFormat handPointStyle = MouseFormat::HAND_POINTING;
151 MouseFormat defaultStyle = MouseFormat::DEFAULT;
152 if (mouseState == MouseState::HOVER) {
153 mousestyle->SetPointerStyle(windowId, handPointStyle);
154 } else {
155 mousestyle->SetPointerStyle(windowId, defaultStyle);
156 }
157 }
158
159 } // namespace OHOS::Ace
160