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 #include "core/components_ng/pattern/list/list_item_model_ng.h"
17
18 #include "base/memory/referenced.h"
19 #include "base/utils/utils.h"
20 #include "core/components_ng/base/frame_node.h"
21 #include "core/components_ng/base/view_stack_processor.h"
22 #include "core/components_ng/pattern/list/list_item_event_hub.h"
23 #include "core/components_ng/pattern/list/list_item_layout_property.h"
24 #include "core/components_ng/pattern/list/list_item_pattern.h"
25 #include "core/components_ng/pattern/list/list_pattern.h"
26 #include "core/components_ng/pattern/scrollable/scrollable_item.h"
27 #include "core/components_ng/pattern/scrollable/scrollable_item_pool.h"
28 #include "core/components_v2/inspector/inspector_constants.h"
29
30 namespace OHOS::Ace::NG {
31
Create(std::function<void (int32_t)> && deepRenderFunc,V2::ListItemStyle listItemStyle)32 void ListItemModelNG::Create(std::function<void(int32_t)>&& deepRenderFunc, V2::ListItemStyle listItemStyle)
33 {
34 auto* stack = ViewStackProcessor::GetInstance();
35 auto nodeId = stack->ClaimNodeId();
36 ACE_LAYOUT_SCOPED_TRACE("Create[%s][self:%d]", V2::LIST_ITEM_ETS_TAG, nodeId);
37 if (deepRenderFunc) {
38 auto deepRender = [nodeId, deepRenderFunc = std::move(deepRenderFunc)]() -> RefPtr<UINode> {
39 CHECK_NULL_RETURN(deepRenderFunc, nullptr);
40 ScopedViewStackProcessor scopedViewStackProcessor;
41 deepRenderFunc(nodeId);
42 return ViewStackProcessor::GetInstance()->Finish();
43 };
44 auto frameNode = ScrollableItemPool::GetInstance().Allocate(V2::LIST_ITEM_ETS_TAG, nodeId,
45 [shallowBuilder = AceType::MakeRefPtr<ShallowBuilder>(std::move(deepRender)), itemStyle = listItemStyle]() {
46 return AceType::MakeRefPtr<ListItemPattern>(shallowBuilder, itemStyle);
47 });
48 stack->Push(frameNode);
49 } else {
50 auto frameNode = FrameNode::GetOrCreateFrameNode(V2::LIST_ITEM_ETS_TAG, nodeId,
51 [listItemStyle]() { return AceType::MakeRefPtr<ListItemPattern>(nullptr, listItemStyle); });
52 stack->Push(frameNode);
53 }
54 }
55
Create()56 void ListItemModelNG::Create()
57 {
58 auto* stack = ViewStackProcessor::GetInstance();
59 auto nodeId = stack->ClaimNodeId();
60 auto frameNode = FrameNode::GetOrCreateFrameNode(V2::LIST_ITEM_ETS_TAG, nodeId,
61 []() { return AceType::MakeRefPtr<ListItemPattern>(nullptr, V2::ListItemStyle::NONE); });
62 stack->Push(frameNode);
63 }
64
OnDidPop()65 void ListItemModelNG::OnDidPop()
66 {
67 auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
68 CHECK_NULL_VOID(frameNode);
69 auto pattern = frameNode->GetPattern<ListItemPattern>();
70 CHECK_NULL_VOID(pattern);
71 pattern->OnDidPop();
72 }
73
CreateFrameNode(int32_t nodeId)74 RefPtr<FrameNode> ListItemModelNG::CreateFrameNode(int32_t nodeId)
75 {
76 auto frameNode = FrameNode::CreateFrameNode(V2::LIST_ITEM_ETS_TAG, nodeId,
77 AceType::MakeRefPtr<ListItemPattern>(nullptr, V2::ListItemStyle::NONE));
78 return frameNode;
79 }
80
81 // use SetDeleteArea to update builder function
SetSwiperAction(std::function<void ()> && startAction,std::function<void ()> && endAction,OnOffsetChangeFunc && onOffsetChangeFunc,V2::SwipeEdgeEffect edgeEffect)82 void ListItemModelNG::SetSwiperAction(std::function<void()>&& startAction, std::function<void()>&& endAction,
83 OnOffsetChangeFunc&& onOffsetChangeFunc, V2::SwipeEdgeEffect edgeEffect)
84 {
85 auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
86 CHECK_NULL_VOID(frameNode);
87 auto pattern = frameNode->GetPattern<ListItemPattern>();
88 CHECK_NULL_VOID(pattern);
89 pattern->SetOffsetChangeCallBack(std::move(onOffsetChangeFunc));
90 ACE_UPDATE_LAYOUT_PROPERTY(ListItemLayoutProperty, EdgeEffect, edgeEffect);
91 }
92
SetSticky(V2::StickyMode stickyMode)93 void ListItemModelNG::SetSticky(V2::StickyMode stickyMode)
94 {
95 ACE_UPDATE_LAYOUT_PROPERTY(ListItemLayoutProperty, StickyMode, stickyMode);
96 }
97
SetEditMode(uint32_t editMode)98 void ListItemModelNG::SetEditMode(uint32_t editMode)
99 {
100 ACE_UPDATE_LAYOUT_PROPERTY(ListItemLayoutProperty, EditMode, editMode);
101 }
102
SetSelectable(bool selectable)103 void ListItemModelNG::SetSelectable(bool selectable)
104 {
105 auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
106 CHECK_NULL_VOID(frameNode);
107 auto pattern = frameNode->GetPattern<ListItemPattern>();
108 CHECK_NULL_VOID(pattern);
109 pattern->SetSelectable(selectable);
110 }
111
SetSelected(bool selected)112 void ListItemModelNG::SetSelected(bool selected)
113 {
114 auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
115 CHECK_NULL_VOID(frameNode);
116 auto pattern = frameNode->GetPattern<ListItemPattern>();
117 CHECK_NULL_VOID(pattern);
118 pattern->SetSelected(selected);
119 auto eventHub = frameNode->GetEventHub<ListItemEventHub>();
120 CHECK_NULL_VOID(eventHub);
121 eventHub->SetCurrentUIState(UI_STATE_SELECTED, selected);
122 }
123
SetSelectChangeEvent(std::function<void (bool)> && changeEvent)124 void ListItemModelNG::SetSelectChangeEvent(std::function<void(bool)>&& changeEvent)
125 {
126 auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
127 CHECK_NULL_VOID(frameNode);
128 auto eventHub = frameNode->GetEventHub<ListItemEventHub>();
129 CHECK_NULL_VOID(eventHub);
130 eventHub->SetSelectChangeEvent(std::move(changeEvent));
131 }
132
SetSelectCallback(OnSelectFunc && selectCallback)133 void ListItemModelNG::SetSelectCallback(OnSelectFunc&& selectCallback)
134 {
135 auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
136 CHECK_NULL_VOID(frameNode);
137 auto eventHub = frameNode->GetEventHub<ListItemEventHub>();
138 CHECK_NULL_VOID(eventHub);
139 eventHub->SetOnSelect(std::move(selectCallback));
140 }
141
SetDeleteArea(std::function<void ()> && builderAction,OnDeleteEvent && onDelete,OnEnterDeleteAreaEvent && onEnterDeleteArea,OnExitDeleteAreaEvent && onExitDeleteArea,OnStateChangedEvent && onStateChange,const Dimension & length,bool isStartArea)142 void ListItemModelNG::SetDeleteArea(std::function<void()>&& builderAction, OnDeleteEvent&& onDelete,
143 OnEnterDeleteAreaEvent&& onEnterDeleteArea, OnExitDeleteAreaEvent&& onExitDeleteArea,
144 OnStateChangedEvent&& onStateChange, const Dimension& length, bool isStartArea)
145 {
146 auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
147 CHECK_NULL_VOID(frameNode);
148 auto eventHub = frameNode->GetEventHub<ListItemEventHub>();
149 CHECK_NULL_VOID(eventHub);
150 auto pattern = frameNode->GetPattern<ListItemPattern>();
151 CHECK_NULL_VOID(pattern);
152 if (isStartArea) {
153 RefPtr<NG::UINode> startNode;
154 if (builderAction) {
155 NG::ScopedViewStackProcessor builderViewStackProcessor;
156 builderAction();
157 startNode = NG::ViewStackProcessor::GetInstance()->Finish();
158 }
159 pattern->SetStartNode(startNode);
160 InstallSwiperCallBack(eventHub, std::move(onDelete), std::move(onEnterDeleteArea), std::move(onExitDeleteArea),
161 std::move(onStateChange), isStartArea);
162 ACE_UPDATE_LAYOUT_PROPERTY(ListItemLayoutProperty, StartDeleteAreaDistance, length);
163 } else {
164 RefPtr<NG::UINode> endNode;
165 if (builderAction) {
166 NG::ScopedViewStackProcessor builderViewStackProcessor;
167 builderAction();
168 endNode = NG::ViewStackProcessor::GetInstance()->Finish();
169 }
170 pattern->SetEndNode(endNode);
171 InstallSwiperCallBack(eventHub, std::move(onDelete), std::move(onEnterDeleteArea), std::move(onExitDeleteArea),
172 std::move(onStateChange), isStartArea);
173 ACE_UPDATE_LAYOUT_PROPERTY(ListItemLayoutProperty, EndDeleteAreaDistance, length);
174 }
175 }
176
InstallSwiperCallBack(RefPtr<ListItemEventHub> eventHub,OnDeleteEvent && onDelete,OnEnterDeleteAreaEvent && onEnterDeleteArea,OnExitDeleteAreaEvent && onExitDeleteArea,OnStateChangedEvent && onStateChange,bool isStartArea)177 void ListItemModelNG::InstallSwiperCallBack(RefPtr<ListItemEventHub> eventHub, OnDeleteEvent&& onDelete,
178 OnEnterDeleteAreaEvent&& onEnterDeleteArea, OnExitDeleteAreaEvent&& onExitDeleteArea,
179 OnStateChangedEvent&& onStateChange, bool isStartArea)
180 {
181 CHECK_NULL_VOID(eventHub);
182 if (isStartArea) {
183 eventHub->SetStartOnDelete(std::move(onDelete));
184 eventHub->SetOnEnterStartDeleteArea(std::move(onEnterDeleteArea));
185 eventHub->SetOnExitStartDeleteArea(std::move(onExitDeleteArea));
186 eventHub->SetStartOnStateChange(std::move(onStateChange));
187 } else {
188 eventHub->SetEndOnDelete(std::move(onDelete));
189 eventHub->SetOnEnterEndDeleteArea(std::move(onEnterDeleteArea));
190 eventHub->SetOnExitEndDeleteArea(std::move(onExitDeleteArea));
191 eventHub->SetEndOnStateChange(std::move(onStateChange));
192 }
193 }
194
SetSelected(FrameNode * frameNode,bool selected)195 void ListItemModelNG::SetSelected(FrameNode* frameNode, bool selected)
196 {
197 CHECK_NULL_VOID(frameNode);
198 auto pattern = frameNode->GetPattern<ListItemPattern>();
199 CHECK_NULL_VOID(pattern);
200 pattern->SetSelected(selected);
201 auto eventHub = frameNode->GetEventHub<ListItemEventHub>();
202 CHECK_NULL_VOID(eventHub);
203 eventHub->SetCurrentUIState(UI_STATE_SELECTED, selected);
204 }
205
SetSelectable(FrameNode * frameNode,bool selectable)206 void ListItemModelNG::SetSelectable(FrameNode* frameNode, bool selectable)
207 {
208 CHECK_NULL_VOID(frameNode);
209 auto pattern = frameNode->GetPattern<ListItemPattern>();
210 CHECK_NULL_VOID(pattern);
211 pattern->SetSelectable(selectable);
212 }
213
SetDeleteArea(FrameNode * frameNode,FrameNode * buildNode,OnDeleteEvent && onDelete,OnEnterDeleteAreaEvent && onEnterDeleteArea,OnExitDeleteAreaEvent && onExitDeleteArea,OnStateChangedEvent && onStateChange,const Dimension & length,bool isStartArea)214 void ListItemModelNG::SetDeleteArea(FrameNode* frameNode, FrameNode* buildNode, OnDeleteEvent&& onDelete,
215 OnEnterDeleteAreaEvent&& onEnterDeleteArea, OnExitDeleteAreaEvent&& onExitDeleteArea,
216 OnStateChangedEvent&& onStateChange, const Dimension& length, bool isStartArea)
217 {
218 CHECK_NULL_VOID(frameNode);
219 auto eventHub = frameNode->GetEventHub<ListItemEventHub>();
220 CHECK_NULL_VOID(eventHub);
221 auto pattern = frameNode->GetPattern<ListItemPattern>();
222 CHECK_NULL_VOID(pattern);
223 if (isStartArea) {
224 const auto startNode = AceType::Claim<UINode>(buildNode);
225 pattern->SetStartNode(startNode);
226
227 eventHub->SetStartOnDelete(std::move(onDelete));
228 eventHub->SetOnEnterStartDeleteArea(std::move(onEnterDeleteArea));
229 eventHub->SetOnExitStartDeleteArea(std::move(onExitDeleteArea));
230 eventHub->SetStartOnStateChange(std::move(onStateChange));
231 ACE_UPDATE_NODE_LAYOUT_PROPERTY(ListItemLayoutProperty, StartDeleteAreaDistance, length, frameNode);
232 } else {
233 const auto endNode = AceType::Claim<UINode>(buildNode);
234 pattern->SetEndNode(endNode);
235
236 eventHub->SetEndOnDelete(std::move(onDelete));
237 eventHub->SetOnEnterEndDeleteArea(std::move(onEnterDeleteArea));
238 eventHub->SetOnExitEndDeleteArea(std::move(onExitDeleteArea));
239 eventHub->SetEndOnStateChange(std::move(onStateChange));
240 ACE_UPDATE_NODE_LAYOUT_PROPERTY(ListItemLayoutProperty, EndDeleteAreaDistance, length, frameNode);
241 }
242 }
243
SetSwiperAction(FrameNode * frameNode,std::function<void ()> && startAction,std::function<void ()> && endAction,OnOffsetChangeFunc && onOffsetChangeFunc,V2::SwipeEdgeEffect edgeEffect)244 void ListItemModelNG::SetSwiperAction(FrameNode* frameNode, std::function<void()>&& startAction,
245 std::function<void()>&& endAction, OnOffsetChangeFunc&& onOffsetChangeFunc, V2::SwipeEdgeEffect edgeEffect)
246 {
247 CHECK_NULL_VOID(frameNode);
248 auto pattern = frameNode->GetPattern<ListItemPattern>();
249 CHECK_NULL_VOID(pattern);
250 pattern->SetOffsetChangeCallBack(std::move(onOffsetChangeFunc));
251 ACE_UPDATE_NODE_LAYOUT_PROPERTY(ListItemLayoutProperty, EdgeEffect, edgeEffect, frameNode);
252 }
253
SetSelectCallback(FrameNode * frameNode,OnSelectFunc && selectCallback)254 void ListItemModelNG::SetSelectCallback(FrameNode* frameNode, OnSelectFunc&& selectCallback)
255 {
256 CHECK_NULL_VOID(frameNode);
257 auto eventHub = frameNode->GetEventHub<ListItemEventHub>();
258 CHECK_NULL_VOID(eventHub);
259 eventHub->SetOnSelect(std::move(selectCallback));
260 }
261
262 } // namespace OHOS::Ace::NG
263