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