• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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/pattern/swiper_indicator/indicator_common/swiper_arrow_pattern.h"
17 
18 #include "base/log/dump_log.h"
19 #include "base/utils/utils.h"
20 #include "core/components/theme/icon_theme.h"
21 #include "core/components_ng/base/frame_node.h"
22 #include "core/components_ng/event/gesture_event_hub.h"
23 #include "core/components_ng/pattern/image/image_pattern.h"
24 #include "core/components_ng/pattern/swiper/swiper_pattern.h"
25 #include "core/components_v2/inspector/inspector_constants.h"
26 #include "core/pipeline_ng/pipeline_context.h"
27 
28 namespace OHOS::Ace::NG {
OnModifyDone()29 void SwiperArrowPattern::OnModifyDone()
30 {
31     Pattern::OnModifyDone();
32     if (isFirstCreate_) {
33         InitNavigationArrow();
34         auto swiperNode = GetSwiperNode();
35         CHECK_NULL_VOID(swiperNode);
36         auto swiperEventHub = swiperNode->GetEventHub<SwiperEventHub>();
37         CHECK_NULL_VOID(swiperEventHub);
38         InitSwiperChangeEvent(swiperEventHub);
39         index_ = GetSwiperArrowLayoutProperty()->GetIndex().value_or(0);
40         isFirstCreate_ = false;
41         InitButtonEvent();
42     } else {
43         UpdateArrowContent();
44     }
45     UpdateButtonNode(index_);
46 }
47 
InitSwiperChangeEvent(const RefPtr<SwiperEventHub> & swiperEventHub)48 void SwiperArrowPattern::InitSwiperChangeEvent(const RefPtr<SwiperEventHub>& swiperEventHub)
49 {
50     ChangeEvent changeEvent = [weak = WeakClaim(this)](int32_t index) {
51         auto pattern = weak.Upgrade();
52         CHECK_NULL_VOID(pattern);
53         pattern->UpdateButtonNode(index);
54     };
55     if (swiperChangeEvent_) {
56         (*swiperChangeEvent_).swap(changeEvent);
57     } else {
58         swiperChangeEvent_ = std::make_shared<ChangeEvent>(std::move(changeEvent));
59         swiperEventHub->AddOnChangeEvent(swiperChangeEvent_);
60     }
61 }
62 
UpdateButtonNode(int32_t index)63 void SwiperArrowPattern::UpdateButtonNode(int32_t index)
64 {
65     index_ = index;
66     auto host = GetHost();
67     CHECK_NULL_VOID(host);
68     auto buttonNode = DynamicCast<FrameNode>(host->GetFirstChild());
69     CHECK_NULL_VOID(buttonNode);
70     auto imageNode = DynamicCast<FrameNode>(buttonNode->GetFirstChild());
71     CHECK_NULL_VOID(imageNode);
72     SetButtonVisible(isVisible_);
73     imageNode->MarkModifyDone();
74 }
75 
InitButtonEvent()76 void SwiperArrowPattern::InitButtonEvent()
77 {
78     auto host = GetHost();
79     CHECK_NULL_VOID(host);
80     auto buttonNode = DynamicCast<FrameNode>(host->GetFirstChild());
81     CHECK_NULL_VOID(buttonNode);
82 
83     auto arrowGestureHub = buttonNode->GetOrCreateGestureEventHub();
84 
85     auto touchCallback = [weak = WeakClaim(this), buttonNode](const TouchEventInfo& info) {
86         auto pattern = weak.Upgrade();
87         CHECK_NULL_VOID(pattern);
88         pattern->ButtonTouchEvent(buttonNode, info.GetTouches().front().GetTouchType());
89     };
90     buttonTouchListenr_ = MakeRefPtr<TouchEventImpl>(std::move(touchCallback));
91     arrowGestureHub->AddTouchEvent(buttonTouchListenr_);
92     arrowGestureHub->SetHitTestMode(HitTestMode::HTMBLOCK);
93 
94     auto hoverCallback = [weak = WeakClaim(this), buttonNode](bool isHovered) {
95         auto pattern = weak.Upgrade();
96         CHECK_NULL_VOID(pattern);
97         pattern->ButtonOnHover(buttonNode, isHovered);
98     };
99     buttonOnHoverListenr_ = MakeRefPtr<InputEvent>(std::move(hoverCallback));
100     auto buttonInputHub = buttonNode->GetOrCreateInputEventHub();
101     buttonInputHub->AddOnHoverEvent(buttonOnHoverListenr_);
102 
103     auto clickCallback = [weak = WeakClaim(this)](const GestureEvent& info) {
104         auto pattern = weak.Upgrade();
105         CHECK_NULL_VOID(pattern);
106         pattern->ButtonClickEvent();
107     };
108     if (buttonClickListenr_) {
109         arrowGestureHub->RemoveClickEvent(buttonClickListenr_);
110     }
111     buttonClickListenr_ = MakeRefPtr<ClickEvent>(std::move(clickCallback));
112     arrowGestureHub->AddClickEvent(buttonClickListenr_);
113 }
114 
ButtonClickEvent()115 void SwiperArrowPattern::ButtonClickEvent()
116 {
117     auto swiperArrowLayoutProperty = GetSwiperArrowLayoutProperty();
118     CHECK_NULL_VOID(swiperArrowLayoutProperty);
119     if (!hoverOnClickFlag_ && swiperArrowLayoutProperty->GetHoverShowValue(false)) {
120         return;
121     }
122     auto swiperNode = GetSwiperNode();
123     CHECK_NULL_VOID(swiperNode);
124     auto swiperPattern = swiperNode->GetPattern<SwiperPattern>();
125     CHECK_NULL_VOID(swiperPattern);
126     auto swiperController = swiperPattern->GetSwiperController();
127     CHECK_NULL_VOID(swiperController);
128     auto host = GetHost();
129     CHECK_NULL_VOID(host);
130     if (host->GetTag() == V2::SWIPER_LEFT_ARROW_ETS_TAG) {
131         swiperController->ShowPrevious();
132     }
133     if (host->GetTag() == V2::SWIPER_RIGHT_ARROW_ETS_TAG) {
134         swiperController->ShowNext();
135     }
136 }
137 
InitNavigationArrow()138 void SwiperArrowPattern::InitNavigationArrow()
139 {
140     auto buttonNode = FrameNode::GetOrCreateFrameNode(V2::BUTTON_ETS_TAG,
141         ElementRegister::GetInstance()->MakeUniqueId(), []() { return AceType::MakeRefPtr<ButtonPattern>(); });
142     auto buttonNodeFocusHub = buttonNode->GetFocusHub();
143     CHECK_NULL_VOID(buttonNodeFocusHub);
144     buttonNodeFocusHub->SetParentFocusable(false);
145     auto swiperArrowLayoutProperty = GetSwiperArrowLayoutProperty();
146     CHECK_NULL_VOID(swiperArrowLayoutProperty);
147     auto imageNode = FrameNode::CreateFrameNode(
148         V2::IMAGE_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<ImagePattern>());
149     auto host = GetHost();
150     CHECK_NULL_VOID(host);
151     auto renderContext = host->GetRenderContext();
152     CHECK_NULL_VOID(renderContext);
153     BorderRadiusProperty radius;
154     radius.SetRadius(swiperArrowLayoutProperty->GetBackgroundSizeValue());
155     renderContext->UpdateBorderRadius(radius);
156     host->AddChild(buttonNode);
157     buttonNode->AddChild(imageNode);
158     UpdateArrowContent();
159 }
160 
TotalCount() const161 int32_t SwiperArrowPattern::TotalCount() const
162 {
163     auto swiperNode = GetSwiperNode();
164     CHECK_NULL_RETURN(swiperNode, 0);
165     auto swiperPattern = swiperNode->GetPattern<SwiperPattern>();
166     CHECK_NULL_RETURN(swiperPattern, 0);
167     return swiperPattern->TotalCount() - 1;
168 }
169 
ButtonTouchEvent(RefPtr<FrameNode> buttonNode,TouchType touchType)170 void SwiperArrowPattern::ButtonTouchEvent(RefPtr<FrameNode> buttonNode, TouchType touchType)
171 {
172     auto swiperArrowLayoutProperty = GetSwiperArrowLayoutProperty();
173     CHECK_NULL_VOID(swiperArrowLayoutProperty);
174     const auto& renderContext = buttonNode->GetRenderContext();
175     CHECK_NULL_VOID(renderContext);
176     auto pipelineContext = PipelineBase::GetCurrentContext();
177     CHECK_NULL_VOID(pipelineContext);
178     auto swiperIndicatorTheme = pipelineContext->GetTheme<SwiperIndicatorTheme>();
179     CHECK_NULL_VOID(swiperIndicatorTheme);
180     Color backgroundColor;
181     if (touchType == TouchType::UP || touchType == TouchType::CANCEL) {
182         isTouch_ = false;
183         if (isHover_) {
184             backgroundColor = swiperIndicatorTheme->GetHoverArrowBackgroundColor();
185             renderContext->ResetBlendBgColor();
186             renderContext->BlendBgColor(backgroundColor);
187         } else {
188             renderContext->ResetBlendBgColor();
189         }
190     }
191     if (!hoverOnClickFlag_ && swiperArrowLayoutProperty->GetHoverShowValue(false)) {
192         return;
193     }
194     if (touchType == TouchType::DOWN) {
195         isTouch_ = true;
196         if (isHover_) {
197             backgroundColor = swiperIndicatorTheme->GetHoverArrowBackgroundColor().BlendColor(
198                 swiperIndicatorTheme->GetClickArrowBackgroundColor());
199         } else {
200             backgroundColor = swiperIndicatorTheme->GetClickArrowBackgroundColor();
201         }
202         renderContext->ResetBlendBgColor();
203         renderContext->BlendBgColor(backgroundColor);
204     }
205 }
206 
ButtonOnHover(RefPtr<FrameNode> buttonNode,bool isHovered)207 void SwiperArrowPattern::ButtonOnHover(RefPtr<FrameNode> buttonNode, bool isHovered)
208 {
209     hoverOnClickFlag_ = isHovered;
210     isHover_ = isHovered;
211     const auto& renderContext = buttonNode->GetRenderContext();
212     CHECK_NULL_VOID(renderContext);
213     auto pipelineContext = PipelineBase::GetCurrentContext();
214     CHECK_NULL_VOID(pipelineContext);
215     auto swiperIndicatorTheme = pipelineContext->GetTheme<SwiperIndicatorTheme>();
216     CHECK_NULL_VOID(swiperIndicatorTheme);
217     Color backgroundColor;
218 
219     auto swiperNode = GetSwiperNode();
220     CHECK_NULL_VOID(swiperNode);
221     auto swiperPattern = swiperNode->GetPattern<SwiperPattern>();
222     CHECK_NULL_VOID(swiperPattern);
223     auto swiperLayoutProperty = swiperPattern->GetLayoutProperty<SwiperLayoutProperty>();
224     CHECK_NULL_VOID(swiperLayoutProperty);
225     if (swiperLayoutProperty->GetHoverShowValue(false)) {
226         swiperPattern->ArrowHover(isHover_);
227     }
228     if (isHovered) {
229         if (isTouch_) {
230             backgroundColor = swiperIndicatorTheme->GetHoverArrowBackgroundColor().BlendColor(
231                 swiperIndicatorTheme->GetClickArrowBackgroundColor());
232         } else {
233             backgroundColor = swiperIndicatorTheme->GetHoverArrowBackgroundColor();
234         }
235         renderContext->ResetBlendBgColor();
236         renderContext->BlendBgColor(backgroundColor);
237     } else {
238         if (isTouch_) {
239             backgroundColor = swiperIndicatorTheme->GetClickArrowBackgroundColor();
240             renderContext->ResetBlendBgColor();
241             renderContext->BlendBgColor(backgroundColor);
242         } else {
243             renderContext->ResetBlendBgColor();
244         }
245     }
246 }
247 
SetButtonVisible(bool visible)248 void SwiperArrowPattern::SetButtonVisible(bool visible)
249 {
250     isVisible_ = visible;
251     auto host = GetHost();
252     CHECK_NULL_VOID(host);
253     auto buttonNode = DynamicCast<FrameNode>(host->GetFirstChild());
254     CHECK_NULL_VOID(buttonNode);
255     const auto& renderContext = buttonNode->GetRenderContext();
256     CHECK_NULL_VOID(renderContext);
257     auto swiperArrowLayoutProperty = GetSwiperArrowLayoutProperty();
258     CHECK_NULL_VOID(swiperArrowLayoutProperty);
259     auto isHoverShow = swiperArrowLayoutProperty->GetHoverShowValue(false);
260     auto hostFocusHub = host->GetFocusHub();
261     CHECK_NULL_VOID(hostFocusHub);
262     if ((host->GetTag() == V2::SWIPER_LEFT_ARROW_ETS_TAG && index_ == 0) ||
263         (host->GetTag() == V2::SWIPER_RIGHT_ARROW_ETS_TAG && index_ == TotalCount())) {
264         if (!swiperArrowLayoutProperty->GetLoopValue(true)) {
265             renderContext->SetVisible(false);
266             hostFocusHub->SetParentFocusable(false);
267             hostFocusHub->LostSelfFocus();
268             return;
269         }
270     }
271     if (isHoverShow) {
272         hostFocusHub->SetParentFocusable(false);
273         hostFocusHub->LostSelfFocus();
274     } else {
275         hostFocusHub->SetParentFocusable(true);
276         visible = true;
277     }
278     renderContext->SetVisible(visible);
279 }
280 
UpdateArrowContent()281 void SwiperArrowPattern::UpdateArrowContent()
282 {
283     auto swiperArrowLayoutProperty = GetSwiperArrowLayoutProperty();
284     CHECK_NULL_VOID(swiperArrowLayoutProperty);
285     auto host = GetHost();
286     CHECK_NULL_VOID(host);
287     auto buttonNode = DynamicCast<FrameNode>(host->GetFirstChild());
288     CHECK_NULL_VOID(buttonNode);
289     buttonNode->GetRenderContext()->UpdateBackgroundColor(
290         swiperArrowLayoutProperty->GetIsShowBackgroundValue(false)
291             ? swiperArrowLayoutProperty->GetBackgroundColorValue(backgroundColor_)
292             : Color::TRANSPARENT);
293     auto buttonLayoutProperty = buttonNode->GetLayoutProperty<ButtonLayoutProperty>();
294     CHECK_NULL_VOID(buttonLayoutProperty);
295     buttonLayoutProperty->UpdateUserDefinedIdealSize(
296         CalcSize(CalcLength(swiperArrowLayoutProperty->GetBackgroundSizeValue()),
297             CalcLength(swiperArrowLayoutProperty->GetBackgroundSizeValue())));
298     backgroundColor_ = buttonNode->GetRenderContext()->GetBackgroundColorValue(Color::TRANSPARENT);
299     RefPtr<FrameNode> imageNode = DynamicCast<FrameNode>(buttonNode->GetFirstChild());
300     CHECK_NULL_VOID(imageNode);
301     auto imageLayoutProperty = imageNode->GetLayoutProperty<ImageLayoutProperty>();
302     CHECK_NULL_VOID(imageLayoutProperty);
303     imageLayoutProperty->UpdateUserDefinedIdealSize(CalcSize(CalcLength(swiperArrowLayoutProperty->GetArrowSizeValue()),
304         CalcLength(swiperArrowLayoutProperty->GetArrowSizeValue())));
305     imageLayoutProperty->UpdateImageFit(ImageFit::FILL);
306     ImageSourceInfo imageSourceInfo;
307     auto swiperLayoutProperty = GetSwiperArrowLayoutProperty();
308     CHECK_NULL_VOID(swiperLayoutProperty);
309     if (V2::SWIPER_LEFT_ARROW_ETS_TAG == GetHost()->GetTag()) {
310         if (swiperLayoutProperty->GetDirection().value_or(Axis::HORIZONTAL) == Axis::HORIZONTAL) {
311             imageSourceInfo.SetResourceId(InternalResource::ResourceId::IC_PUBLIC_ARROW_LEFT_SVG);
312         } else {
313             imageSourceInfo.SetResourceId(InternalResource::ResourceId::IC_PUBLIC_ARROW_UP_SVG);
314         }
315     } else if (V2::SWIPER_RIGHT_ARROW_ETS_TAG == GetHost()->GetTag()) {
316         if (swiperLayoutProperty->GetDirection().value_or(Axis::HORIZONTAL) == Axis::HORIZONTAL) {
317             imageSourceInfo.SetResourceId(InternalResource::ResourceId::IC_PUBLIC_ARROW_RIGHT_SVG);
318         } else {
319             imageSourceInfo.SetResourceId(InternalResource::ResourceId::IC_PUBLIC_ARROW_DOWN_SVG);
320         }
321     }
322     imageSourceInfo.SetFillColor(swiperArrowLayoutProperty->GetArrowColorValue());
323     if (!swiperArrowLayoutProperty->GetEnabledValue(true)) {
324         auto pipelineContext = PipelineBase::GetCurrentContext();
325         CHECK_NULL_VOID(pipelineContext);
326         auto swiperIndicatorTheme = pipelineContext->GetTheme<SwiperIndicatorTheme>();
327         CHECK_NULL_VOID(swiperIndicatorTheme);
328         buttonNode->GetRenderContext()->UpdateBackgroundColor(
329             backgroundColor_.BlendOpacity(swiperIndicatorTheme->GetArrowDisabledAlpha()));
330         imageSourceInfo.SetFillColor(swiperArrowLayoutProperty->GetArrowColorValue().BlendOpacity(
331             swiperIndicatorTheme->GetArrowDisabledAlpha()));
332     }
333     imageLayoutProperty->UpdateImageSourceInfo(imageSourceInfo);
334     imageNode->MarkModifyDone();
335 }
336 
DumpAdvanceInfo()337 void SwiperArrowPattern::DumpAdvanceInfo()
338 {
339     DumpLog::GetInstance().AddDesc("index:" + std::to_string(index_));
340     isTouch_ ? DumpLog::GetInstance().AddDesc("isTouch:true") : DumpLog::GetInstance().AddDesc("isTouch:false");
341     isHover_ ? DumpLog::GetInstance().AddDesc("isHover:true") : DumpLog::GetInstance().AddDesc("isHover:false");
342     hoverOnClickFlag_ ? DumpLog::GetInstance().AddDesc("hoverOnClickFlag:true")
343                       : DumpLog::GetInstance().AddDesc("hoverOnClickFlag:false");
344 }
345 } // namespace OHOS::Ace::NG
346