1 /*
2  * Copyright (c) 2021 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_LIST_RENDER_LIST_ITEM_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_LIST_RENDER_LIST_ITEM_H
18 
19 #include "core/common/vibrator/vibrator.h"
20 #include "core/components/common/properties/border.h"
21 #include "core/components/display/render_display.h"
22 #include "core/components/list/interactive_effect.h"
23 #include "core/components/list/layout_manager.h"
24 #include "core/components/list/list_item_component.h"
25 #include "core/components/scroll/scroll_position_controller.h"
26 #include "core/event/ace_event_helper.h"
27 #include "core/gestures/click_recognizer.h"
28 #include "core/gestures/raw_recognizer.h"
29 #include "core/pipeline/base/render_node.h"
30 
31 namespace OHOS::Ace {
32 
33 constexpr double RADIUS_START = 10000.0;
34 constexpr double RADIUS_END = 1000.0;
35 
36 class RenderList;
37 class RenderListItem : public RenderNode {
38     DECLARE_ACE_TYPE(RenderListItem, RenderNode);
39 
40 public:
41     ~RenderListItem() override = default;
42     void Dump() override;
43 
44     static RefPtr<RenderNode> Create();
45     void HandleFocusEvent(bool focus, bool isInGroup = false);
46     void ShowFocusAnimation(bool focus, const Rect& listRect, double scale = TV_ITEM_SCALE);
47     void UpdateItemFocusRect(double scale);
48     void NotifyGroupPrimaryChange();
49 
GetType()50     std::string GetType() const
51     {
52         return type_;
53     }
54 
SetIndex(int32_t index)55     void SetIndex(int32_t index)
56     {
57         index_ = index;
58     }
59 
GetIndex()60     int32_t GetIndex() const
61     {
62         return index_;
63     }
64 
GetFlags()65     uint32_t GetFlags() const
66     {
67         return flags_;
68     }
69 
TestFlag(uint32_t flag)70     bool TestFlag(uint32_t flag) const
71     {
72         return (flags_ & flag);
73     }
74 
RemoveFlag(uint32_t flag)75     void RemoveFlag(uint32_t flag)
76     {
77         flags_ &= ~flag;
78     }
79 
80     double GetPositionInList() const;
81 
GetOperation()82     int32_t GetOperation() const
83     {
84         return op_;
85     }
86 
SetOperation(int32_t op)87     void SetOperation(int32_t op)
88     {
89         op_ = op;
90     }
91 
IsFocused()92     bool IsFocused() const
93     {
94         return focused_;
95     }
96 
SetFocused(bool focused)97     void SetFocused(bool focused)
98     {
99         focused_ = focused;
100     }
101 
SetGrid(int32_t grid)102     void SetGrid(int32_t grid)
103     {
104         grid_ = grid;
105     }
106 
GetGrid()107     int32_t GetGrid() const
108     {
109         return grid_;
110     }
111 
GetColumnSpan()112     int32_t GetColumnSpan() const
113     {
114         return columnSpan_;
115     }
116 
GetSticky()117     bool GetSticky() const
118     {
119         return sticky_;
120     }
121 
SetSticky(bool sticky)122     void SetSticky(bool sticky)
123     {
124         sticky_ = sticky;
125     }
126 
GetStickyMode()127     StickyMode GetStickyMode() const
128     {
129         return stickyMode_;
130     }
131 
GetNearByOpacitySticky()132     bool GetNearByOpacitySticky() const
133     {
134         return nearByOpacitySticky_;
135     }
136 
SetNearByOpacitySticky(bool nearBy)137     void SetNearByOpacitySticky(bool nearBy)
138     {
139         nearByOpacitySticky_ = nearBy;
140     }
141 
GetClonedBySticky()142     bool GetClonedBySticky() const
143     {
144         return clonedBySticky_;
145     }
146 
SetClonedBySticky(bool clonedBySticky)147     void SetClonedBySticky(bool clonedBySticky)
148     {
149         clonedBySticky_ = clonedBySticky;
150     }
151 
GetSupportScale()152     bool GetSupportScale() const
153     {
154         return supportScale_;
155     }
156 
GetSupportOpacity()157     bool GetSupportOpacity() const
158     {
159         return supportOpacity_;
160     }
161 
GetSupportClick()162     bool GetSupportClick() const
163     {
164         return supportClick_;
165     }
166 
GetPrimary()167     bool GetPrimary() const
168     {
169         return primary_;
170     }
171 
SetPrimaryChange(bool change)172     void SetPrimaryChange(bool change)
173     {
174         primaryChange_ = change;
175     }
176 
GetPrimaryChange()177     bool GetPrimaryChange() const
178     {
179         return primaryChange_;
180     }
181 
SetPrimary(bool primary)182     void SetPrimary(bool primary)
183     {
184         if (primary_ != primary) {
185             primaryChange_ = true;
186             auto item = AceType::DynamicCast<ListItemComponent>(itemComponent_);
187             if (item) {
188                 item->SetPrimary(primary);
189             }
190         }
191         primary_ = primary;
192     }
193 
GetCurPrimary()194     bool GetCurPrimary() const
195     {
196         return curPrimary_;
197     }
198 
SetCurPrimary(bool primary)199     void SetCurPrimary(bool primary)
200     {
201         curPrimary_ = primary;
202     }
203 
GetRedraw()204     bool GetRedraw() const
205     {
206         return redraw_;
207     }
208 
SetRedraw(bool redraw)209     void SetRedraw(bool redraw)
210     {
211         redraw_ = redraw;
212     }
213 
214     void HandleItemEffect(bool isFromRotate = false);
215 
216     // judge is item at center of viewport or not, used on watch
217     bool IsItemCenter(bool isVertical, Size viewport);
218 
GetCurrentState()219     ItemState GetCurrentState() const
220     {
221         return currentState_;
222     }
223 
SetCurrentState(ItemState state)224     void SetCurrentState(ItemState state)
225     {
226         currentState_ = state;
227     }
228 
229     using ListItemClickedFunc = std::function<void()>;
RegisterClickedCallback(const ListItemClickedFunc & clicked)230     void RegisterClickedCallback(const ListItemClickedFunc& clicked)
231     {
232         clicked_ = clicked;
233     }
234 
GetRenderListItem(const RefPtr<RenderNode> & renderNode)235     static RefPtr<RenderListItem> GetRenderListItem(const RefPtr<RenderNode>& renderNode)
236     {
237         RefPtr<RenderNode> listItem = renderNode;
238         while (listItem) {
239             if (AceType::InstanceOf<RenderListItem>(listItem)) {
240                 return AceType::DynamicCast<RenderListItem>(listItem);
241             }
242 
243             auto& children = listItem->GetChildren();
244             if (children.empty()) {
245                 return nullptr;
246             }
247             listItem = children.front();
248         }
249         return nullptr;
250     }
251 
GetScrollController()252     const RefPtr<ScrollPositionController>& GetScrollController() const
253     {
254         return scrollController_;
255     }
256 
SetScrollController(const RefPtr<ScrollPositionController> & controller)257     void SetScrollController(const RefPtr<ScrollPositionController>& controller)
258     {
259         scrollController_ = controller;
260     }
261 
GetStickyRadius()262     double GetStickyRadius() const
263     {
264         return stickyRadius_;
265     }
266 
SetExpandOpacity(int32_t opacity)267     void SetExpandOpacity(int32_t opacity)
268     {
269         expandOpacity_ = opacity;
270     }
271 
SetStretch(bool isStretch)272     void SetStretch(bool isStretch)
273     {
274         isStretch_ = isStretch;
275     }
276 
SetPreLayoutSize(const Size & size)277     void SetPreLayoutSize(const Size& size)
278     {
279         preLayoutSize_ = size;
280     }
281 
GetPreLayoutSize()282     const Size& GetPreLayoutSize() const
283     {
284         return preLayoutSize_;
285     }
286 
GetScaleFactor()287     double GetScaleFactor() const
288     {
289         return scaleFactor_;
290     }
291 
GetOpacityFactor()292     double GetOpacityFactor() const
293     {
294         return opacityFactor_;
295     }
296 
GetTransitionEffect()297     TransitionEffect GetTransitionEffect() const
298     {
299         return transitionEffect_;
300     }
301 
GetSelfAlign()302     FlexAlign GetSelfAlign() const
303     {
304         return selfAlign_;
305     }
306 
SetSelfAlign(FlexAlign selfAlign)307     void SetSelfAlign(FlexAlign selfAlign)
308     {
309         selfAlign_ = selfAlign;
310     }
311 
312     void OnGroupClicked();
313     void HandleStickyEvent(bool sticky);
314     void HandleClicked();
315     void CalculateScaleFactorOnWatch();
316     void RunCardTransitionAnimation(double shiftHeight);
317     void StopCardTransitionAnimation();
318     RRect GetRRect() const;
319 
320 protected:
321     RenderListItem();
322 
323     void Update(const RefPtr<Component>& component) override;
324     void ResetFocusEffect();
325     void OnTouchTestHit(
326         const Offset& coordinateOffset, const TouchRestrict& touchRestrict, TouchTestResult& result) override;
327 
328     void UpdateAccessibilityAttr();
329     void MoveToViewPort();
330     void PlayPressDownAnimation();
331     void PlayPressUpAnimation();
332     void OnCancelPressAnimation() override;
333     RefPtr<RenderList> GetRenderList() const;
334     bool NeedDivider();
335     void PerformLayout() override;
336     bool IsListVertical();
337     bool IsLastItem();
338     Size GetPaintSize() const;
339     EdgePx GetMarginInPx() const;
340     Border GetFocusBorder() const;
341 
342     RefPtr<ClickRecognizer> clickRecognizer_;
343     RefPtr<RawRecognizer> touchRecognizer_;
344     RefPtr<Vibrator> vibrator_;
345     RefPtr<InteractiveEffect> focusController_;
346     RefPtr<RenderDisplay> renderDisplay_;
347     bool needVibrate_ = true;
348     bool rotationVibrate_ = false;
349     bool supportScale_ = true;
350     bool supportOpacity_ = false;
351     bool supportClick_ = true;
352     bool isStretch_ = false;
353     bool isTitle_ = false;
354     int32_t expandOpacity_ = UINT8_MAX;
355     bool primary_ = false;
356     bool curPrimary_ = false;
357     bool primaryChange_ = false;
358     bool needDivider_ = false;
359     bool isActive_ = false;
360     Color clickColor_ = Color::TRANSPARENT;
361     FlexAlign selfAlign_ = FlexAlign::AUTO;
362 
363     Dimension dividerOrigin_;
364     Dimension dividerLength_;
365     Dimension dividerHeight_ = DIVIDER_DEFAULT_HEIGHT;
366     Color dividerColor_;
367     StickyMode stickyMode_ = StickyMode::NONE;
368     double scaleFactor_ = 1.0;
369     double opacityFactor_ = 1.0;
370     RRect focusAnimationRRect_;
371     bool makeCardTransition_ = false;
372 
373 private:
374     void Initialize();
375     Offset GetPaintOffset() const;
376     std::function<void()> clickEvent_;
377     std::function<void(const std::string&)> stickyEvent_;
378     Size preLayoutSize_;
379     int32_t index_ = -1;
380     uint32_t flags_ = 0;
381     int32_t op_ = LIST_ITEM_OP_NONE;
382     std::string type_;
383     Color focusAnimationColor_ = Color::WHITE;
384     bool focused_ = false;
385     int32_t grid_ = -1;
386     int32_t columnSpan_ = 1;
387     ItemState lastState_ = ItemState::NONE;
388     ItemState currentState_ = ItemState::NONE;
389     RefPtr<ScrollPositionController> scrollController_;
390     bool pressAnimation_ = false;
391     bool redraw_ = false;
392     bool sticky_ = false;
393     bool nearByOpacitySticky_ = false;
394     bool clonedBySticky_ = false;
395     double stickyRadius_ = RADIUS_END;
396     RefPtr<Component> itemComponent_;
397 
398     ListItemClickedFunc clicked_;
399 
400     TransitionEffect transitionEffect_ = TransitionEffect::NONE;
401 };
402 
403 } // namespace OHOS::Ace
404 
405 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_LIST_RENDER_LIST_ITEM_H
406