• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_SWIPER_SWIPER_EVENT_HUB_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_SWIPER_SWIPER_EVENT_HUB_H
18 
19 #include <algorithm>
20 #include <memory>
21 
22 #include "base/memory/ace_type.h"
23 #include "core/common/recorder/event_recorder.h"
24 #include "core/common/recorder/node_data_cache.h"
25 #include "core/components_ng/base/frame_node.h"
26 #include "core/components_ng/event/event_hub.h"
27 #include "core/components_ng/pattern/swiper/swiper_model.h"
28 
29 namespace OHOS::Ace::NG {
30 
31 enum class Direction {
32     PRE = 0,
33     NEXT,
34 };
35 using ChangeIndicatorEvent = std::function<void()>;
36 using IndicatorIndexChangeEvent = std::function<void(int32_t index)>;
37 using ChangeEvent = std::function<void(int32_t index)>;
38 using ChangeEventPtr = std::shared_ptr<ChangeEvent>;
39 using ChangeEventWithPreIndex = std::function<void(int32_t preIndex, int32_t currentIndex)>;
40 using ChangeEventWithPreIndexPtr = std::shared_ptr<ChangeEventWithPreIndex>;
41 using ChangeDoneEvent = std::function<void()>;
42 
43 class SwiperEventHub : public EventHub {
44     DECLARE_ACE_TYPE(SwiperEventHub, EventHub)
45 
46 public:
47     SwiperEventHub() = default;
48     ~SwiperEventHub() override = default;
49 
50     /* Using shared_ptr to enable event modification without adding again */
AddOnChangeEvent(const ChangeEventPtr & changeEvent)51     void AddOnChangeEvent(const ChangeEventPtr& changeEvent)
52     {
53         changeEvents_.emplace_back(changeEvent);
54     }
55 
AddOnChangeEventWithPreIndex(const ChangeEventWithPreIndexPtr & changeEventWithPreIndex)56     void AddOnChangeEventWithPreIndex(const ChangeEventWithPreIndexPtr& changeEventWithPreIndex)
57     {
58         changeEventsWithPreIndex_.emplace_back(changeEventWithPreIndex);
59     }
60 
SetIndicatorOnChange(ChangeIndicatorEvent && changeEvent)61     void SetIndicatorOnChange(ChangeIndicatorEvent&& changeEvent)
62     {
63         changeIndicatorEvent_ = std::move(changeEvent);
64     }
65 
SetIndicatorIndexChangeEvent(IndicatorIndexChangeEvent && indicatorIndexChangeEvent)66     void SetIndicatorIndexChangeEvent(IndicatorIndexChangeEvent&& indicatorIndexChangeEvent)
67     {
68         indicatorIndexChangeEvent_ = std::move(indicatorIndexChangeEvent);
69     }
70 
SetChangeDoneEvent(ChangeDoneEvent && changeDoneEvent)71     void SetChangeDoneEvent(ChangeDoneEvent&& changeDoneEvent)
72     {
73         changeDoneEvent_ = std::move(changeDoneEvent);
74     }
75 
AddAnimationStartEvent(const AnimationStartEventPtr & animationStartEvent)76     void AddAnimationStartEvent(const AnimationStartEventPtr& animationStartEvent)
77     {
78         animationStartEvents_.emplace_back(animationStartEvent);
79     }
80 
AddAnimationEndEvent(const AnimationEndEventPtr & animationEndEvent)81     void AddAnimationEndEvent(const AnimationEndEventPtr& animationEndEvent)
82     {
83         animationEndEvents_.emplace_back(animationEndEvent);
84     }
85 
SetGestureSwipeEvent(GestureSwipeEvent && gestureSwipeEvent)86     void SetGestureSwipeEvent(GestureSwipeEvent&& gestureSwipeEvent)
87     {
88         gestureSwipeEvent_ = std::move(gestureSwipeEvent);
89     }
90 
FireChangeDoneEvent(bool direction)91     void FireChangeDoneEvent(bool direction)
92     {
93         if (changeDoneEvent_) {
94             if (direction) {
95                 direction_ = Direction::NEXT;
96             } else {
97                 direction_ = Direction::PRE;
98             }
99             changeDoneEvent_();
100         }
101     }
102 
FireChangeEvent(int32_t preIndex,int32_t currentIndex)103     void FireChangeEvent(int32_t preIndex, int32_t currentIndex) const
104     {
105         ACE_SCOPED_TRACE("Swiper FireChangeEvent, preIndex: %d currentIndex: %d eventSize: %zu",
106             preIndex, currentIndex, changeEvents_.size() + changeEventsWithPreIndex_.size());
107         if (!changeEvents_.empty()) {
108             std::for_each(
109                 changeEvents_.begin(), changeEvents_.end(), [currentIndex](const ChangeEventPtr& changeEvent) {
110                     auto event = *changeEvent;
111                     event(currentIndex);
112                 });
113         }
114         if (!changeEventsWithPreIndex_.empty()) {
115             std::for_each(changeEventsWithPreIndex_.begin(), changeEventsWithPreIndex_.end(),
116                 [preIndex, currentIndex](const ChangeEventWithPreIndexPtr& changeEventWithPreIndex) {
117                     auto event = *changeEventWithPreIndex;
118                     event(preIndex, currentIndex);
119                 });
120         }
121 
122         if (Recorder::EventRecorder::Get().IsComponentRecordEnable()) {
123             Recorder::EventParamsBuilder builder;
124             auto host = GetFrameNode();
125             if (host) {
126                 auto id = host->GetInspectorIdValue("");
127                 builder.SetId(id).SetType(host->GetHostTag()).SetDescription(host->GetAutoEventParamValue(""));
128                 if (!id.empty()) {
129                     Recorder::NodeDataCache::Get().PutInt(host, id, currentIndex);
130                 }
131             }
132             builder.SetIndex(currentIndex);
133             Recorder::EventRecorder::Get().OnChange(std::move(builder));
134         }
135     }
136 
FireIndicatorChangeEvent(int32_t index)137     void FireIndicatorChangeEvent(int32_t index) const
138     {
139         if (changeIndicatorEvent_) {
140             changeIndicatorEvent_();
141         }
142     }
143 
FireIndicatorIndexChangeEvent(int32_t index)144     void FireIndicatorIndexChangeEvent(int32_t index) const
145     {
146         if (indicatorIndexChangeEvent_) {
147             indicatorIndexChangeEvent_(index);
148         }
149     }
150 
GetDirection()151     Direction GetDirection()
152     {
153         return direction_;
154     }
155 
FireAnimationStartEvent(int32_t index,int32_t targetIndex,const AnimationCallbackInfo & info)156     void FireAnimationStartEvent(int32_t index, int32_t targetIndex, const AnimationCallbackInfo& info)
157     {
158         if (!animationStartEvents_.empty()) {
159             std::for_each(animationStartEvents_.begin(), animationStartEvents_.end(),
160                 [index, targetIndex, info](const AnimationStartEventPtr& animationStartEvent) {
161                     auto event = *animationStartEvent;
162                     event(index, targetIndex, info);
163                 });
164         }
165         // animationEnd callback need to be fired after animationStart callback, use flag for protection.
166         ++aniStartCalledCount_;
167         if (delayCallback_) {
168             TAG_LOGI(AceLogTag::ACE_SWIPER, "the timing of the animation callback has been corrected");
169             delayCallback_();
170             delayCallback_ = nullptr;
171         }
172     }
173 
FireAnimationEndEvent(int32_t index,const AnimationCallbackInfo & info)174     void FireAnimationEndEvent(int32_t index, const AnimationCallbackInfo& info)
175     {
176         if (aniStartCalledCount_ <= 0) {
177             delayCallback_ = [weak = WeakClaim(this), index, info]() {
178                 auto hub = weak.Upgrade();
179                 CHECK_NULL_VOID(hub);
180                 hub->FireAnimationEndEvent(index, info);
181             };
182             return;
183         }
184         if (!animationEndEvents_.empty()) {
185             std::for_each(animationEndEvents_.begin(), animationEndEvents_.end(),
186                 [index, info](const AnimationEndEventPtr& animationEndEvent) {
187                     auto event = *animationEndEvent;
188                     event(index, info);
189                 });
190         }
191         --aniStartCalledCount_;
192     }
193 
FireAnimationEndOnForceEvent(int32_t index,const AnimationCallbackInfo & info)194     void FireAnimationEndOnForceEvent(int32_t index, const AnimationCallbackInfo& info)
195     {
196         if (aniStartCalledCount_ <= 0) {
197             delayCallback_ = [weak = WeakClaim(this), index, info]() {
198                 auto hub = weak.Upgrade();
199                 CHECK_NULL_VOID(hub);
200                 hub->FireAnimationEndOnForceEvent(index, info);
201             };
202             return;
203         }
204         if (!animationEndEvents_.empty()) {
205             auto context = GetFrameNode()->GetContext();
206             CHECK_NULL_VOID(context);
207             context->AddBuildFinishCallBack([this, index, info]() {
208                 std::for_each(animationEndEvents_.begin(), animationEndEvents_.end(),
209                     [index, info](const AnimationEndEventPtr& animationEndEvent) {
210                         auto event = *animationEndEvent;
211                         event(index, info);
212                     });
213             });
214         }
215         --aniStartCalledCount_;
216     }
217 
FireGestureSwipeEvent(int32_t index,const AnimationCallbackInfo & info)218     void FireGestureSwipeEvent(int32_t index, const AnimationCallbackInfo& info) const
219     {
220         if (gestureSwipeEvent_) {
221             // gestureSwipeEvent_ may be overwrite in its invoke, so copy it first
222             auto event = gestureSwipeEvent_;
223             event(index, info);
224         }
225     }
226 
227 private:
228     Direction direction_;
229     std::list<ChangeEventPtr> changeEvents_;
230     std::list<ChangeEventWithPreIndexPtr> changeEventsWithPreIndex_;
231     ChangeDoneEvent changeDoneEvent_;
232     ChangeIndicatorEvent changeIndicatorEvent_;
233     IndicatorIndexChangeEvent indicatorIndexChangeEvent_;
234     std::list<AnimationStartEventPtr> animationStartEvents_;
235     std::list<AnimationEndEventPtr> animationEndEvents_;
236     GestureSwipeEvent gestureSwipeEvent_;
237     int32_t aniStartCalledCount_ = 0;
238     std::function<void()> delayCallback_;
239 };
240 
241 } // namespace OHOS::Ace::NG
242 
243 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_SWIPER_SWIPER_EVENT_HUB_H