@cc-component/cc-ex-component 1.1.6 → 1.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/core/BaseReference.ts +40 -0
- package/assets/{video/VideoComponent.ts.meta → core/BaseReference.ts.meta} +1 -1
- package/assets/core/BaseViewModelData.ts +12 -0
- package/assets/{video/Interface.ts.meta → core/BaseViewModelData.ts.meta} +1 -1
- package/assets/core/ReferenceComponent.ts +317 -0
- package/assets/core/ViewModel.ts +542 -0
- package/assets/{video/IVideo.ts.meta → core/ViewModel.ts.meta} +9 -9
- package/assets/ex/EXButton.ts +191 -0
- package/assets/ex/EXButton.ts.meta +9 -0
- package/assets/ex/ExCommon.ts +6 -4
- package/assets/ex/ExTool.ts +116 -0
- package/assets/ex/ExTool.ts.meta +9 -0
- package/assets/lib/collectView/lib-ext/custom-grid-flow-layout.ts +105 -0
- package/assets/lib/collectView/lib-ext/custom-grid-flow-layout.ts.meta +9 -0
- package/assets/lib/collectView/lib-ext/horizontal-center-layout.ts +84 -0
- package/assets/lib/collectView/lib-ext/horizontal-center-layout.ts.meta +9 -0
- package/assets/lib/collectView/lib-ext/yx-card-page-layout.ts +132 -0
- package/assets/lib/collectView/lib-ext/yx-card-page-layout.ts.meta +9 -0
- package/assets/lib/collectView/lib-ext/yx-carousel-layout.ts +156 -0
- package/assets/lib/collectView/lib-ext/yx-carousel-layout.ts.meta +9 -0
- package/assets/lib/collectView/lib-ext/yx-cover-layout.ts +405 -0
- package/assets/lib/collectView/lib-ext/yx-cover-layout.ts.meta +9 -0
- package/assets/lib/collectView/lib-ext/yx-masonry-flow-layout.ts +194 -0
- package/assets/lib/collectView/lib-ext/yx-masonry-flow-layout.ts.meta +9 -0
- package/assets/lib/collectView/lib-ext/yx-page-view.ts +232 -0
- package/assets/lib/collectView/lib-ext/yx-page-view.ts.meta +9 -0
- package/assets/lib/collectView/lib-ext/yx-table-view.ts +159 -0
- package/assets/lib/collectView/lib-ext/yx-table-view.ts.meta +9 -0
- package/assets/lib/collectView/lib-ext.meta +9 -0
- package/assets/lib/collectView/lib_collect/yx-collection-view.ts +1549 -0
- package/assets/lib/collectView/lib_collect/yx-collection-view.ts.meta +9 -0
- package/assets/lib/collectView/lib_collect/yx-compact-flow-layout.ts +364 -0
- package/assets/lib/collectView/lib_collect/yx-compact-flow-layout.ts.meta +9 -0
- package/assets/lib/collectView/lib_collect/yx-flow-layout.ts +909 -0
- package/assets/lib/collectView/lib_collect/yx-flow-layout.ts.meta +9 -0
- package/assets/lib/collectView/lib_collect/yx-table-layout.ts +352 -0
- package/assets/lib/collectView/lib_collect/yx-table-layout.ts.meta +9 -0
- package/assets/lib/collectView/lib_collect.meta +9 -0
- package/assets/{video/list.meta → lib/collectView.meta} +9 -9
- package/assets/lib/tableView/IListView.ts +17 -0
- package/assets/lib/tableView/IListView.ts.meta +9 -0
- package/assets/lib/tableView/ListView.ts +197 -0
- package/assets/lib/tableView/ListView.ts.meta +9 -0
- package/assets/lib/tableView/ListViewPage.ts +1048 -0
- package/assets/lib/tableView/ListViewPage.ts.meta +9 -0
- package/assets/lib/tableView/ListViewPageLoop.ts +922 -0
- package/assets/lib/tableView/ListViewPageLoop.ts.meta +1 -0
- package/assets/lib/tableView/TableView.ts +82 -0
- package/assets/lib/tableView/TableView.ts.meta +9 -0
- package/assets/lib/tableView.meta +9 -0
- package/assets/{video.meta → lib.meta} +1 -1
- package/assets/platform/Interface.ts +15 -10
- package/assets/platform/android/AndroidModule.ts +12 -0
- package/assets/platform/android/AndroidModule.ts.meta +9 -0
- package/assets/platform/android/AndroidSDK.ts +1 -2
- package/assets/platform/base/PlatfprmModule.ts +44 -29
- package/assets/platform/base/SDKBase.ts +2 -2
- package/assets/platform/base/TTSDK.ts +21 -10
- package/assets/platform/base/WXSDK.ts +15 -16
- package/assets/platform/wx/MiniSDK.ts +41 -3
- package/assets/platform/wx/wxmini.d.ts +2 -2
- package/index.ts +0 -1
- package/package.json +1 -1
- package/assets/core/ReferenceCollector.ts +0 -172
- package/assets/video/IVideo.ts +0 -73
- package/assets/video/Interface.ts +0 -25
- package/assets/video/VideoComponent.prefab +0 -614
- package/assets/video/VideoComponent.prefab.meta +0 -13
- package/assets/video/VideoComponent.ts +0 -33
- package/assets/video/VideoManager.ts +0 -399
- package/assets/video/VideoManager.ts.meta +0 -9
- package/assets/video/VideoModule.ts +0 -137
- package/assets/video/VideoModule.ts.meta +0 -9
- package/assets/video/VideoPlayTT.ts +0 -338
- package/assets/video/VideoPlayTT.ts.meta +0 -9
- package/assets/video/VideoPlayWX.ts +0 -274
- package/assets/video/VideoPlayWX.ts.meta +0 -9
- package/assets/video/VideoPlayWeb.ts +0 -228
- package/assets/video/VideoPlayWeb.ts.meta +0 -9
- /package/assets/core/{ReferenceCollector.ts.meta → ReferenceComponent.ts.meta} +0 -0
|
@@ -0,0 +1,909 @@
|
|
|
1
|
+
import { _decorator, math, UITransform } from 'cc';
|
|
2
|
+
import { YXBinaryLayout, YXCollectionView, YXEdgeInsets, YXIndexPath, YXLayoutAttributes } from './yx-collection-view';
|
|
3
|
+
|
|
4
|
+
const _rectOut = new math.Rect()
|
|
5
|
+
|
|
6
|
+
enum _yx_flow_layout_alignment {
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* 节点在所处行/列内居中
|
|
10
|
+
*/
|
|
11
|
+
CENTER,
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* 这个配置表示向前对齐,节点会向排列开始的方向对齐,具体表现为:
|
|
15
|
+
* 当列表为垂直方向列表时,如果节点排列方向是由上至下排列的,这个值就代表上对齐,如果节点排列方向是由下至上排列的,这个值就代表下对齐
|
|
16
|
+
* 当列表为水平方向列表时,如果节点排列方向是由左至右排列的,这个值就代表左对齐,如果节点排列方向是由右至左排列的,这个值就代表右对齐
|
|
17
|
+
*/
|
|
18
|
+
FORWARD,
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* 这个配置表示向后对齐,具体表现跟 FORWARD 相反
|
|
22
|
+
*/
|
|
23
|
+
BACKWARD,
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
enum _yx_flow_layout_priority {
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* 以 spacing 配置为准,弱化 sectionInset 配置
|
|
31
|
+
*/
|
|
32
|
+
CENTER,
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* 以 sectionInset 配置为准,弱化 spacing 配置
|
|
36
|
+
*/
|
|
37
|
+
SIDE,
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* 以 sectionInset.left 为准,弱化 right 配置
|
|
41
|
+
* 仅支持垂直滚动列表
|
|
42
|
+
*/
|
|
43
|
+
LEFT,
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* 以 sectionInset.right 为准,弱化 left 配置
|
|
47
|
+
* 仅支持垂直滚动列表
|
|
48
|
+
*/
|
|
49
|
+
RIGHT,
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* 以 sectionInset.top 为准,弱化 bottom 配置
|
|
53
|
+
* 仅支持水平滚动列表
|
|
54
|
+
*/
|
|
55
|
+
TOP,
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* 以 sectionInset.bottom 为准,弱化 top 配置
|
|
59
|
+
* 仅支持水平滚动列表
|
|
60
|
+
*/
|
|
61
|
+
BOTTOM,
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
enum _yx_flow_layout_reverse_mode {
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* 默认方案
|
|
68
|
+
* 水平排列方向为从左至右排列
|
|
69
|
+
* 垂直排列方向为从上至下排列
|
|
70
|
+
*/
|
|
71
|
+
NONE = 0,
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* 这个标识会将水平排列方向变为从右至左排列
|
|
75
|
+
*/
|
|
76
|
+
HORIZONTAL = 1 << 0,
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* 这个标识会将垂直排列方向变为从下至上排列
|
|
80
|
+
*/
|
|
81
|
+
VERTICAL = 1 << 1,
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* flow-layout 约定了每个区允许配置一个区头和一个区尾
|
|
86
|
+
* 设置 sectionHeaderSize 开启区头
|
|
87
|
+
* 设置 sectionFooterSize 开启区尾
|
|
88
|
+
* 通过 YXCollectionView 的 supplementaryForItemAt 返回区头/区尾对应的节点
|
|
89
|
+
*
|
|
90
|
+
* 在使用列表的补充视图 (supplementary) 相关的接口时,可以通过这个 kinds 枚举判断是区头还是区尾
|
|
91
|
+
*/
|
|
92
|
+
enum _yx_flow_layout_section_kinds {
|
|
93
|
+
HEADER = 'flow-layout-HEADER',
|
|
94
|
+
FOOTER = 'flow-layout-FOOTER',
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* 流式布局
|
|
99
|
+
* 支持水平/垂直方向排列滚动
|
|
100
|
+
*/
|
|
101
|
+
export class YXFlowLayout extends YXBinaryLayout {
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* 是否开启分页滚动效果
|
|
105
|
+
*/
|
|
106
|
+
pagingEnabled: boolean = false
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* 分页吸附动画时间
|
|
110
|
+
*/
|
|
111
|
+
pagingAnimationDuration: number = 0.5
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* 节点在行(垂直列表)或者列(水平列表)内的对齐方式
|
|
115
|
+
*/
|
|
116
|
+
alignment: _yx_flow_layout_alignment = YXFlowLayout.Alignment.CENTER
|
|
117
|
+
static Alignment = _yx_flow_layout_alignment
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* 约束优先级
|
|
121
|
+
*/
|
|
122
|
+
priority: _yx_flow_layout_priority = YXFlowLayout.Priority.LEFT
|
|
123
|
+
static Priority = _yx_flow_layout_priority
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* 当 priority 设置为 SIDE 模式,并且最后一行或者最后一列只有一个单元 cell 时,这一个 cell 如何对齐
|
|
127
|
+
* 默认是 null,也就是垂直列表时靠左,水平列表时靠上
|
|
128
|
+
* 正常情况下,一般不需要关心这个配置,除非列表是 SIDE 模式并且需要调整最后一个单元 cell 的对齐方式时才需要调整这个配置
|
|
129
|
+
*/
|
|
130
|
+
lastItemPriority: _yx_flow_layout_priority = null
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* 反向排列节点
|
|
134
|
+
* @example
|
|
135
|
+
* // 水平反向排列
|
|
136
|
+
* layout.reverse = YXFlowLayout.Reverse.HORIZONTAL
|
|
137
|
+
*
|
|
138
|
+
* // 垂直反向排列
|
|
139
|
+
* layout.reverse = YXFlowLayout.Reverse.VERTICAL
|
|
140
|
+
*
|
|
141
|
+
* // 水平/垂直都反向排列
|
|
142
|
+
* layout.reverse = YXFlowLayout.Reverse.HORIZONTAL | YXFlowLayout.Reverse.VERTICAL
|
|
143
|
+
*/
|
|
144
|
+
reverse: _yx_flow_layout_reverse_mode = YXFlowLayout.Reverse.NONE
|
|
145
|
+
static Reverse = _yx_flow_layout_reverse_mode
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* 元素大小
|
|
149
|
+
*/
|
|
150
|
+
itemSize: math.Size | ((indexPath: YXIndexPath, layout: YXFlowLayout, collectionView: YXCollectionView) => math.Size) = new math.Size(100, 100)
|
|
151
|
+
getItemSize(): math.Size {
|
|
152
|
+
if (this.itemSize instanceof Function == false) {
|
|
153
|
+
return this.itemSize
|
|
154
|
+
}
|
|
155
|
+
throw new Error("YXFlowLayout: 动态配置的布局参数不支持直接获取,请检查自己的布局逻辑并谨慎的通过动态配置自己获取,注意避免死循环");
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* 元素之间垂直间距
|
|
160
|
+
*/
|
|
161
|
+
verticalSpacing: number | ((section: number, layout: YXFlowLayout, collectionView: YXCollectionView) => number) = 0
|
|
162
|
+
getVerticalSpacing(): number {
|
|
163
|
+
if (this.verticalSpacing instanceof Function == false) {
|
|
164
|
+
return this.verticalSpacing
|
|
165
|
+
}
|
|
166
|
+
throw new Error("YXFlowLayout: 动态配置的布局参数不支持直接获取,请检查自己的布局逻辑并谨慎的通过动态配置自己获取,注意避免死循环");
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* 元素之间水平间距
|
|
171
|
+
*/
|
|
172
|
+
horizontalSpacing: number | ((section: number, layout: YXFlowLayout, collectionView: YXCollectionView) => number) = 0
|
|
173
|
+
getHorizontalSpacing(): number {
|
|
174
|
+
if (this.horizontalSpacing instanceof Function == false) {
|
|
175
|
+
return this.horizontalSpacing
|
|
176
|
+
}
|
|
177
|
+
throw new Error("YXFlowLayout: 动态配置的布局参数不支持直接获取,请检查自己的布局逻辑并谨慎的通过动态配置自己获取,注意避免死循环");
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* 边距
|
|
182
|
+
*/
|
|
183
|
+
sectionInset: YXEdgeInsets | ((section: number, layout: YXFlowLayout, collectionView: YXCollectionView) => YXEdgeInsets) = YXEdgeInsets.ZERO
|
|
184
|
+
getSectionInset(): YXEdgeInsets {
|
|
185
|
+
if (this.sectionInset instanceof Function == false) {
|
|
186
|
+
return this.sectionInset
|
|
187
|
+
}
|
|
188
|
+
throw new Error("YXFlowLayout: 动态配置的布局参数不支持直接获取,请检查自己的布局逻辑并谨慎的通过动态配置自己获取,注意避免死循环");
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* 区头大小
|
|
193
|
+
*/
|
|
194
|
+
sectionHeaderSize: math.Size | ((section: number, layout: YXFlowLayout, collectionView: YXCollectionView) => math.Size) = null
|
|
195
|
+
getSectionHeaderSize(): math.Size {
|
|
196
|
+
if (this.sectionHeaderSize instanceof Function == false) {
|
|
197
|
+
return this.sectionHeaderSize
|
|
198
|
+
}
|
|
199
|
+
throw new Error("YXFlowLayout: 动态配置的布局参数不支持直接获取,请检查自己的布局逻辑并谨慎的通过动态配置自己获取,注意避免死循环");
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* 区尾大小
|
|
204
|
+
*/
|
|
205
|
+
sectionFooterSize: math.Size | ((section: number, layout: YXFlowLayout, collectionView: YXCollectionView) => math.Size) = null
|
|
206
|
+
getSectionFooterSize(): math.Size {
|
|
207
|
+
if (this.sectionFooterSize instanceof Function == false) {
|
|
208
|
+
return this.sectionFooterSize
|
|
209
|
+
}
|
|
210
|
+
throw new Error("YXFlowLayout: 动态配置的布局参数不支持直接获取,请检查自己的布局逻辑并谨慎的通过动态配置自己获取,注意避免死循环");
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* 访问定义的区头/区尾标识
|
|
215
|
+
*/
|
|
216
|
+
static SupplementaryKinds = _yx_flow_layout_section_kinds
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* 钉住 header 的位置 ( header 吸附在列表可见范围内 )
|
|
220
|
+
* 垂直列表设置了垂直反向排列 或者 水平列表设置了水平反向排列时,此配置不会生效
|
|
221
|
+
*/
|
|
222
|
+
sectionHeadersPinToVisibleBounds: boolean = false
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* 钉住 footer 的位置 ( footer 吸附在列表可见范围内 )
|
|
226
|
+
* 垂直列表设置了垂直反向排列 或者 水平列表设置了水平反向排列时,此配置不会生效
|
|
227
|
+
*/
|
|
228
|
+
sectionFootersPinToVisibleBounds: boolean = false
|
|
229
|
+
|
|
230
|
+
protected sectionPinToVisibleBoundsSupported = false // 是否支持 Pin 区头/区尾业务
|
|
231
|
+
protected originalHeaderRect: Map<number, math.Rect> = new Map() // 保存所有 header 的原始位置
|
|
232
|
+
protected originalFooterRect: Map<number, math.Rect> = new Map() // 保存所有 footer 的原始位置
|
|
233
|
+
|
|
234
|
+
prepare(collectionView: YXCollectionView): void {
|
|
235
|
+
this.originalHeaderRect.clear()
|
|
236
|
+
this.originalFooterRect.clear()
|
|
237
|
+
this.sectionPinToVisibleBoundsSupported = (this.sectionHeadersPinToVisibleBounds || this.sectionFootersPinToVisibleBounds)
|
|
238
|
+
if (collectionView.scrollDirection == YXCollectionView.ScrollDirection.HORIZONTAL) {
|
|
239
|
+
if (this.reverse & _yx_flow_layout_reverse_mode.HORIZONTAL) { this.sectionPinToVisibleBoundsSupported = false }
|
|
240
|
+
this._horizontal(collectionView)
|
|
241
|
+
return
|
|
242
|
+
}
|
|
243
|
+
if (collectionView.scrollDirection == YXCollectionView.ScrollDirection.VERTICAL) {
|
|
244
|
+
if (this.reverse & _yx_flow_layout_reverse_mode.VERTICAL) { this.sectionPinToVisibleBoundsSupported = false }
|
|
245
|
+
this._vertical(collectionView)
|
|
246
|
+
return
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
initOffset(collectionView: YXCollectionView): void {
|
|
251
|
+
if (collectionView.scrollDirection == YXCollectionView.ScrollDirection.HORIZONTAL) {
|
|
252
|
+
collectionView.scrollView.scrollToLeft(0)
|
|
253
|
+
return
|
|
254
|
+
}
|
|
255
|
+
if (collectionView.scrollDirection == YXCollectionView.ScrollDirection.VERTICAL) {
|
|
256
|
+
collectionView.scrollView.scrollToTop(0)
|
|
257
|
+
return
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
targetOffset(collectionView: YXCollectionView, touchMoveVelocity: math.Vec3, startOffset: math.Vec2, originTargetOffset: math.Vec2, originScrollDuration: number): { offset: math.Vec2; time?: number; attenuated?: boolean; } | null {
|
|
262
|
+
if (this.pagingEnabled == false) {
|
|
263
|
+
return null
|
|
264
|
+
}
|
|
265
|
+
let offset = collectionView.scrollView.getScrollOffset()
|
|
266
|
+
offset.x = - offset.x
|
|
267
|
+
let threshold = 0.2
|
|
268
|
+
if (collectionView.scrollDirection == YXCollectionView.ScrollDirection.HORIZONTAL) {
|
|
269
|
+
let idx = Math.round(offset.x / collectionView.scrollView.view.width)
|
|
270
|
+
let r = touchMoveVelocity.x / collectionView.scrollView.view.width
|
|
271
|
+
if (startOffset && Math.abs(r) >= threshold) {
|
|
272
|
+
idx = Math.round(startOffset.x / collectionView.scrollView.view.width) + (r > 0 ? -1 : 1)
|
|
273
|
+
}
|
|
274
|
+
offset.x = idx * collectionView.scrollView.view.width
|
|
275
|
+
}
|
|
276
|
+
if (collectionView.scrollDirection == YXCollectionView.ScrollDirection.VERTICAL) {
|
|
277
|
+
let idx = Math.round(offset.y / collectionView.scrollView.view.height)
|
|
278
|
+
let r = touchMoveVelocity.y / collectionView.scrollView.view.height
|
|
279
|
+
if (startOffset && Math.abs(r) >= threshold) {
|
|
280
|
+
idx = Math.round(startOffset.y / collectionView.scrollView.view.height) + (r > 0 ? 1 : -1)
|
|
281
|
+
}
|
|
282
|
+
offset.y = idx * collectionView.scrollView.view.height
|
|
283
|
+
}
|
|
284
|
+
return { offset: offset, time: this.pagingAnimationDuration }
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
protected _horizontal(collectionView: YXCollectionView) {
|
|
288
|
+
collectionView.scrollView.horizontal = true
|
|
289
|
+
collectionView.scrollView.vertical = false
|
|
290
|
+
let contentSize = collectionView.node.getComponent(UITransform).contentSize.clone()
|
|
291
|
+
let allAttributes: YXLayoutAttributes[] = []
|
|
292
|
+
|
|
293
|
+
let numberOfSections = collectionView.getNumberOfSections()
|
|
294
|
+
|
|
295
|
+
let sectionMaxX = 0
|
|
296
|
+
for (let section = 0; section < numberOfSections; section++) {
|
|
297
|
+
let numberOfItems = collectionView.getNumberOfItems(section)
|
|
298
|
+
let verticalSpacing = this.verticalSpacing instanceof Function ? this.verticalSpacing(section, this, collectionView) : this.verticalSpacing
|
|
299
|
+
let horizontalSpacing = this.horizontalSpacing instanceof Function ? this.horizontalSpacing(section, this, collectionView) : this.horizontalSpacing
|
|
300
|
+
let sectionInset = this.sectionInset instanceof Function ? this.sectionInset(section, this, collectionView) : this.sectionInset
|
|
301
|
+
|
|
302
|
+
// header
|
|
303
|
+
let sectionHeaderSize = this.sectionHeaderSize instanceof Function ? this.sectionHeaderSize(section, this, collectionView) : this.sectionHeaderSize
|
|
304
|
+
if (sectionHeaderSize && sectionHeaderSize.width > 0 && sectionHeaderSize.height > 0) {
|
|
305
|
+
let indexPath = new YXIndexPath(section, 0)
|
|
306
|
+
let attr = YXLayoutAttributes.layoutAttributesForSupplementary(indexPath, _yx_flow_layout_section_kinds.HEADER)
|
|
307
|
+
attr.zIndex = 1
|
|
308
|
+
attr.frame.y = sectionInset.top
|
|
309
|
+
attr.frame.x = sectionMaxX
|
|
310
|
+
attr.frame.size = sectionHeaderSize
|
|
311
|
+
allAttributes.push(attr)
|
|
312
|
+
sectionMaxX = attr.frame.xMax + sectionInset.left
|
|
313
|
+
this.originalHeaderRect.set(attr.indexPath.section, attr.frame.clone())
|
|
314
|
+
} else {
|
|
315
|
+
sectionMaxX += sectionInset.left
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
// cells
|
|
319
|
+
let whole = new _yx_flow_layout_whole()
|
|
320
|
+
whole.verticalSpacing = verticalSpacing
|
|
321
|
+
whole.horizontalSpacing = horizontalSpacing
|
|
322
|
+
whole.sectionInset = sectionInset
|
|
323
|
+
whole.offset = sectionMaxX
|
|
324
|
+
whole.attrs = []
|
|
325
|
+
whole.containerWidth = 0
|
|
326
|
+
whole.containerHeight = contentSize.height
|
|
327
|
+
whole.alignment = this.alignment
|
|
328
|
+
whole.priority = this.priority
|
|
329
|
+
whole.lastItemPriority = this.lastItemPriority
|
|
330
|
+
whole.reverse = this.reverse
|
|
331
|
+
|
|
332
|
+
for (let item = 0; item < numberOfItems; item++) {
|
|
333
|
+
let indexPath = new YXIndexPath(section, item)
|
|
334
|
+
let itemSize = this.itemSize instanceof Function ? this.itemSize(indexPath, this, collectionView) : this.itemSize
|
|
335
|
+
|
|
336
|
+
let attr = whole.layout_horizontal_item(indexPath, itemSize)
|
|
337
|
+
if (attr == null) {
|
|
338
|
+
// 返回 null 表示摆不下了,需要换列排列
|
|
339
|
+
whole.layout_horizontal_complet()
|
|
340
|
+
whole.offset = whole.offset + whole.containerWidth + horizontalSpacing
|
|
341
|
+
whole.containerWidth = 0
|
|
342
|
+
whole.attrs = []
|
|
343
|
+
attr = whole.layout_horizontal_item(indexPath, itemSize)
|
|
344
|
+
}
|
|
345
|
+
if (attr) {
|
|
346
|
+
allAttributes.push(attr)
|
|
347
|
+
}
|
|
348
|
+
sectionMaxX = Math.max(sectionMaxX, whole.offset + whole.containerWidth)
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
whole.layout_horizontal_complet()
|
|
352
|
+
sectionMaxX += sectionInset.right
|
|
353
|
+
|
|
354
|
+
// footer
|
|
355
|
+
let sectionFooterSize = this.sectionFooterSize instanceof Function ? this.sectionFooterSize(section, this, collectionView) : this.sectionFooterSize
|
|
356
|
+
if (sectionFooterSize && sectionFooterSize.width > 0 && sectionFooterSize.height > 0) {
|
|
357
|
+
let indexPath = new YXIndexPath(section, 0)
|
|
358
|
+
let attr = YXLayoutAttributes.layoutAttributesForSupplementary(indexPath, _yx_flow_layout_section_kinds.FOOTER)
|
|
359
|
+
attr.zIndex = 1
|
|
360
|
+
attr.frame.y = sectionInset.top
|
|
361
|
+
attr.frame.x = sectionMaxX
|
|
362
|
+
attr.frame.size = sectionFooterSize
|
|
363
|
+
allAttributes.push(attr)
|
|
364
|
+
sectionMaxX = attr.frame.xMax + sectionInset.left
|
|
365
|
+
this.originalFooterRect.set(attr.indexPath.section, attr.frame.clone())
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
this._reverse_horizontal(allAttributes, sectionMaxX)
|
|
370
|
+
this.attributes = allAttributes
|
|
371
|
+
contentSize.width = Math.max(contentSize.width, sectionMaxX)
|
|
372
|
+
this.contentSize = contentSize
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
protected _reverse_horizontal(attributes: YXLayoutAttributes[], contentWidth: number) {
|
|
376
|
+
if (this.reverse & _yx_flow_layout_reverse_mode.HORIZONTAL) {
|
|
377
|
+
for (let index = 0; index < attributes.length; index++) {
|
|
378
|
+
const element = attributes[index];
|
|
379
|
+
element.frame.x = contentWidth - element.frame.x - element.frame.width;
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
protected _vertical(collectionView: YXCollectionView) {
|
|
385
|
+
collectionView.scrollView.horizontal = false
|
|
386
|
+
collectionView.scrollView.vertical = true
|
|
387
|
+
let contentSize = collectionView.node.getComponent(UITransform).contentSize.clone()
|
|
388
|
+
let allAttributes: YXLayoutAttributes[] = []
|
|
389
|
+
|
|
390
|
+
let numberOfSections = collectionView.getNumberOfSections()
|
|
391
|
+
|
|
392
|
+
let sectionMaxY = 0
|
|
393
|
+
for (let section = 0; section < numberOfSections; section++) {
|
|
394
|
+
let numberOfItems = collectionView.getNumberOfItems(section)
|
|
395
|
+
let verticalSpacing = this.verticalSpacing instanceof Function ? this.verticalSpacing(section, this, collectionView) : this.verticalSpacing
|
|
396
|
+
let horizontalSpacing = this.horizontalSpacing instanceof Function ? this.horizontalSpacing(section, this, collectionView) : this.horizontalSpacing
|
|
397
|
+
let sectionInset = this.sectionInset instanceof Function ? this.sectionInset(section, this, collectionView) : this.sectionInset
|
|
398
|
+
|
|
399
|
+
// header
|
|
400
|
+
let sectionHeaderSize = this.sectionHeaderSize instanceof Function ? this.sectionHeaderSize(section, this, collectionView) : this.sectionHeaderSize
|
|
401
|
+
if (sectionHeaderSize && sectionHeaderSize.width > 0 && sectionHeaderSize.height > 0) {
|
|
402
|
+
let indexPath = new YXIndexPath(section, 0)
|
|
403
|
+
let attr = YXLayoutAttributes.layoutAttributesForSupplementary(indexPath, _yx_flow_layout_section_kinds.HEADER)
|
|
404
|
+
attr.zIndex = 1
|
|
405
|
+
attr.frame.y = sectionMaxY
|
|
406
|
+
attr.frame.x = sectionInset.left
|
|
407
|
+
attr.frame.size = sectionHeaderSize
|
|
408
|
+
allAttributes.push(attr)
|
|
409
|
+
sectionMaxY = attr.frame.yMax + sectionInset.top
|
|
410
|
+
this.originalHeaderRect.set(attr.indexPath.section, attr.frame.clone())
|
|
411
|
+
} else {
|
|
412
|
+
sectionMaxY += sectionInset.top
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
// cells
|
|
416
|
+
let whole = new _yx_flow_layout_whole()
|
|
417
|
+
whole.verticalSpacing = verticalSpacing
|
|
418
|
+
whole.horizontalSpacing = horizontalSpacing
|
|
419
|
+
whole.sectionInset = sectionInset
|
|
420
|
+
whole.offset = sectionMaxY
|
|
421
|
+
whole.attrs = []
|
|
422
|
+
whole.containerWidth = contentSize.width
|
|
423
|
+
whole.containerHeight = 0
|
|
424
|
+
whole.alignment = this.alignment
|
|
425
|
+
whole.priority = this.priority
|
|
426
|
+
whole.lastItemPriority = this.lastItemPriority
|
|
427
|
+
whole.reverse = this.reverse
|
|
428
|
+
|
|
429
|
+
for (let item = 0; item < numberOfItems; item++) {
|
|
430
|
+
let indexPath = new YXIndexPath(section, item)
|
|
431
|
+
let itemSize = this.itemSize instanceof Function ? this.itemSize(indexPath, this, collectionView) : this.itemSize
|
|
432
|
+
|
|
433
|
+
let attr = whole.layout_vertical_item(indexPath, itemSize)
|
|
434
|
+
if (attr == null) {
|
|
435
|
+
// 返回 null 表示摆不下了,需要换行排列
|
|
436
|
+
whole.layout_vertical_complet()
|
|
437
|
+
whole.offset = whole.offset + whole.containerHeight + verticalSpacing
|
|
438
|
+
whole.containerHeight = 0
|
|
439
|
+
whole.attrs = []
|
|
440
|
+
attr = whole.layout_vertical_item(indexPath, itemSize)
|
|
441
|
+
}
|
|
442
|
+
if (attr) {
|
|
443
|
+
allAttributes.push(attr)
|
|
444
|
+
}
|
|
445
|
+
sectionMaxY = Math.max(sectionMaxY, whole.offset + whole.containerHeight)
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
whole.layout_vertical_complet()
|
|
449
|
+
sectionMaxY += sectionInset.bottom
|
|
450
|
+
|
|
451
|
+
// footer
|
|
452
|
+
let sectionFooterSize = this.sectionFooterSize instanceof Function ? this.sectionFooterSize(section, this, collectionView) : this.sectionFooterSize
|
|
453
|
+
if (sectionFooterSize && sectionFooterSize.width > 0 && sectionFooterSize.height > 0) {
|
|
454
|
+
let indexPath = new YXIndexPath(section, 0)
|
|
455
|
+
let attr = YXLayoutAttributes.layoutAttributesForSupplementary(indexPath, _yx_flow_layout_section_kinds.FOOTER)
|
|
456
|
+
attr.zIndex = 1
|
|
457
|
+
attr.frame.y = sectionMaxY
|
|
458
|
+
attr.frame.x = sectionInset.left
|
|
459
|
+
attr.frame.size = sectionFooterSize
|
|
460
|
+
allAttributes.push(attr)
|
|
461
|
+
sectionMaxY = attr.frame.yMax
|
|
462
|
+
this.originalFooterRect.set(attr.indexPath.section, attr.frame.clone())
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
this._reverse_vertical(allAttributes, sectionMaxY)
|
|
467
|
+
this.attributes = allAttributes
|
|
468
|
+
contentSize.height = Math.max(contentSize.height, sectionMaxY)
|
|
469
|
+
this.contentSize = contentSize
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
protected _reverse_vertical(attributes: YXLayoutAttributes[], contentHeight: number) {
|
|
473
|
+
if (this.reverse & _yx_flow_layout_reverse_mode.VERTICAL) {
|
|
474
|
+
for (let index = 0; index < attributes.length; index++) {
|
|
475
|
+
const element = attributes[index];
|
|
476
|
+
element.frame.y = contentHeight - element.frame.y - element.frame.height;
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
layoutAttributesForElementsInRect(rect: math.Rect, collectionView: YXCollectionView): YXLayoutAttributes[] {
|
|
482
|
+
if (!this.sectionPinToVisibleBoundsSupported) {
|
|
483
|
+
return super.layoutAttributesForElementsInRect(rect, collectionView)
|
|
484
|
+
}
|
|
485
|
+
if (collectionView.scrollDirection === YXCollectionView.ScrollDirection.HORIZONTAL) {
|
|
486
|
+
return this.layoutAttributesForElementsInRect_horizontal(rect, collectionView)
|
|
487
|
+
}
|
|
488
|
+
if (collectionView.scrollDirection === YXCollectionView.ScrollDirection.VERTICAL) {
|
|
489
|
+
return this.layoutAttributesForElementsInRect_vertical(rect, collectionView)
|
|
490
|
+
}
|
|
491
|
+
return this.attributes
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
protected layoutAttributesForElementsInRect_horizontal(rect: math.Rect, collectionView: YXCollectionView): YXLayoutAttributes[] {
|
|
495
|
+
let numberOfSections = collectionView.getNumberOfSections()
|
|
496
|
+
let scrollOffset = collectionView.scrollView.getScrollOffset()
|
|
497
|
+
scrollOffset.x = - scrollOffset.x
|
|
498
|
+
for (let index = 0; index < this.attributes.length; index++) {
|
|
499
|
+
const element = this.attributes[index];
|
|
500
|
+
if (element.elementCategory === 'Supplementary') {
|
|
501
|
+
|
|
502
|
+
if (this.sectionHeadersPinToVisibleBounds && element.supplementaryKinds === _yx_flow_layout_section_kinds.HEADER) {
|
|
503
|
+
const originalFrame = this.originalHeaderRect.get(element.indexPath.section)
|
|
504
|
+
element.frame.x = originalFrame.x
|
|
505
|
+
if (scrollOffset.x > originalFrame.x) {
|
|
506
|
+
element.frame.x = scrollOffset.x
|
|
507
|
+
}
|
|
508
|
+
const nextOriginalFrame = this.getNextOriginalFrame(element.indexPath.section, _yx_flow_layout_section_kinds.FOOTER, numberOfSections)
|
|
509
|
+
if (nextOriginalFrame) {
|
|
510
|
+
if (element.frame.xMax > nextOriginalFrame.x) {
|
|
511
|
+
element.frame.x = nextOriginalFrame.x - element.frame.width
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
if (this.sectionFootersPinToVisibleBounds && element.supplementaryKinds === _yx_flow_layout_section_kinds.FOOTER) {
|
|
517
|
+
let bottom = scrollOffset.x + collectionView.scrollView.view.width
|
|
518
|
+
const originalFrame = this.originalFooterRect.get(element.indexPath.section)
|
|
519
|
+
const previousOriginalFrame = this.getPreviousOriginalFrame(element.indexPath.section, _yx_flow_layout_section_kinds.HEADER)
|
|
520
|
+
element.frame.x = originalFrame.x
|
|
521
|
+
if (bottom < originalFrame.xMax) {
|
|
522
|
+
element.frame.x = bottom - element.frame.width
|
|
523
|
+
if (previousOriginalFrame) {
|
|
524
|
+
if (element.frame.x < previousOriginalFrame.xMax) {
|
|
525
|
+
element.frame.x = previousOriginalFrame.xMax
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
return this.attributes
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
protected layoutAttributesForElementsInRect_vertical(rect: math.Rect, collectionView: YXCollectionView): YXLayoutAttributes[] {
|
|
536
|
+
let numberOfSections = collectionView.getNumberOfSections()
|
|
537
|
+
let scrollOffset = collectionView.scrollView.getScrollOffset()
|
|
538
|
+
for (let index = 0; index < this.attributes.length; index++) {
|
|
539
|
+
const element = this.attributes[index];
|
|
540
|
+
if (element.elementCategory === 'Supplementary') {
|
|
541
|
+
|
|
542
|
+
if (this.sectionHeadersPinToVisibleBounds && element.supplementaryKinds === _yx_flow_layout_section_kinds.HEADER) {
|
|
543
|
+
const originalFrame = this.originalHeaderRect.get(element.indexPath.section)
|
|
544
|
+
element.frame.y = originalFrame.y
|
|
545
|
+
if (scrollOffset.y > originalFrame.y) {
|
|
546
|
+
element.frame.y = scrollOffset.y
|
|
547
|
+
}
|
|
548
|
+
const nextOriginalFrame = this.getNextOriginalFrame(element.indexPath.section, _yx_flow_layout_section_kinds.FOOTER, numberOfSections)
|
|
549
|
+
if (nextOriginalFrame) {
|
|
550
|
+
if (element.frame.yMax > nextOriginalFrame.y) {
|
|
551
|
+
element.frame.y = nextOriginalFrame.y - element.frame.height
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
if (this.sectionFootersPinToVisibleBounds && element.supplementaryKinds === _yx_flow_layout_section_kinds.FOOTER) {
|
|
557
|
+
let bottom = scrollOffset.y + collectionView.scrollView.view.height
|
|
558
|
+
const originalFrame = this.originalFooterRect.get(element.indexPath.section)
|
|
559
|
+
const previousOriginalFrame = this.getPreviousOriginalFrame(element.indexPath.section, _yx_flow_layout_section_kinds.HEADER)
|
|
560
|
+
element.frame.y = originalFrame.y
|
|
561
|
+
if (bottom < originalFrame.yMax) {
|
|
562
|
+
element.frame.y = bottom - element.frame.height
|
|
563
|
+
if (previousOriginalFrame) {
|
|
564
|
+
if (element.frame.y < previousOriginalFrame.yMax) {
|
|
565
|
+
element.frame.y = previousOriginalFrame.yMax
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
return this.attributes
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
protected getNextOriginalFrame(section: number, kinds: _yx_flow_layout_section_kinds, total: number) {
|
|
576
|
+
if (section >= total) { return null }
|
|
577
|
+
if (kinds === _yx_flow_layout_section_kinds.HEADER) {
|
|
578
|
+
let result = this.originalHeaderRect.get(section)
|
|
579
|
+
if (result) { return result }
|
|
580
|
+
return this.getNextOriginalFrame(section, _yx_flow_layout_section_kinds.FOOTER, total)
|
|
581
|
+
}
|
|
582
|
+
if (kinds === _yx_flow_layout_section_kinds.FOOTER) {
|
|
583
|
+
let result = this.originalFooterRect.get(section)
|
|
584
|
+
if (result) { return result }
|
|
585
|
+
return this.getNextOriginalFrame(section + 1, _yx_flow_layout_section_kinds.HEADER, total)
|
|
586
|
+
}
|
|
587
|
+
return null
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
protected getPreviousOriginalFrame(section: number, kinds: _yx_flow_layout_section_kinds) {
|
|
591
|
+
if (section < 0) { return null }
|
|
592
|
+
if (kinds === _yx_flow_layout_section_kinds.HEADER) {
|
|
593
|
+
let result = this.originalHeaderRect.get(section)
|
|
594
|
+
if (result) { return result }
|
|
595
|
+
return this.getPreviousOriginalFrame(section - 1, _yx_flow_layout_section_kinds.FOOTER)
|
|
596
|
+
}
|
|
597
|
+
if (kinds === _yx_flow_layout_section_kinds.FOOTER) {
|
|
598
|
+
let result = this.originalFooterRect.get(section)
|
|
599
|
+
if (result) { return result }
|
|
600
|
+
return this.getPreviousOriginalFrame(section, _yx_flow_layout_section_kinds.HEADER)
|
|
601
|
+
}
|
|
602
|
+
return null
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
shouldUpdateAttributesForBoundsChange(): boolean {
|
|
606
|
+
return this.sectionPinToVisibleBoundsSupported
|
|
607
|
+
}
|
|
608
|
+
shouldUpdateAttributesZIndex(): boolean {
|
|
609
|
+
return this.sectionPinToVisibleBoundsSupported
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
onDestroy(): void {
|
|
613
|
+
this.attributes = []
|
|
614
|
+
this.attributes = null
|
|
615
|
+
|
|
616
|
+
this.originalHeaderRect.clear()
|
|
617
|
+
this.originalHeaderRect = null
|
|
618
|
+
|
|
619
|
+
this.originalFooterRect.clear()
|
|
620
|
+
this.originalHeaderRect = null
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
export namespace YXFlowLayout {
|
|
625
|
+
export type Alignment = _yx_flow_layout_alignment
|
|
626
|
+
export type Priority = _yx_flow_layout_priority
|
|
627
|
+
export type Reverse = _yx_flow_layout_reverse_mode
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
/**
|
|
631
|
+
* 实现按行/列排列节点 && 调整对齐方式/约束优先级
|
|
632
|
+
* 一个 whole 对象管理一行或者一列的节点
|
|
633
|
+
*/
|
|
634
|
+
class _yx_flow_layout_whole {
|
|
635
|
+
|
|
636
|
+
/**
|
|
637
|
+
* 当前这块内容的起始位置
|
|
638
|
+
* 可能是 x,可能是 y,取决于排列方向
|
|
639
|
+
*/
|
|
640
|
+
offset: number
|
|
641
|
+
|
|
642
|
+
/**
|
|
643
|
+
* flow layout 部分参数
|
|
644
|
+
*/
|
|
645
|
+
verticalSpacing: number
|
|
646
|
+
horizontalSpacing: number
|
|
647
|
+
sectionInset: YXEdgeInsets
|
|
648
|
+
alignment: _yx_flow_layout_alignment
|
|
649
|
+
priority: _yx_flow_layout_priority
|
|
650
|
+
lastItemPriority: _yx_flow_layout_priority
|
|
651
|
+
reverse: _yx_flow_layout_reverse_mode
|
|
652
|
+
|
|
653
|
+
/**
|
|
654
|
+
* 容器相关的参数
|
|
655
|
+
*/
|
|
656
|
+
containerWidth: number
|
|
657
|
+
containerHeight: number
|
|
658
|
+
|
|
659
|
+
/**
|
|
660
|
+
* 这块内容区域目前已经摆放的节点
|
|
661
|
+
*/
|
|
662
|
+
attrs: YXLayoutAttributes[] = []
|
|
663
|
+
|
|
664
|
+
/**
|
|
665
|
+
* 检查传进来的位置是否跟当前这块内容的其他节点重叠
|
|
666
|
+
*/
|
|
667
|
+
intersects(rect: math.Rect) {
|
|
668
|
+
for (let index = 0; index < this.attrs.length; index++) {
|
|
669
|
+
const element = this.attrs[index];
|
|
670
|
+
math.Rect.intersection(_rectOut, element.frame, rect)
|
|
671
|
+
if (_rectOut.width > 0 && _rectOut.height > 0) {
|
|
672
|
+
return true
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
return false
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
/**
|
|
679
|
+
* 垂直方向列表的节点的排列规则
|
|
680
|
+
*/
|
|
681
|
+
layout_vertical_item(indexPath: YXIndexPath, itemSize: math.Size) {
|
|
682
|
+
if (this.attrs.length <= 0) {
|
|
683
|
+
let attributes = YXLayoutAttributes.layoutAttributesForCell(indexPath)
|
|
684
|
+
attributes.frame.set(this.sectionInset.left, this.offset, itemSize.width, itemSize.height)
|
|
685
|
+
this.attrs.push(attributes)
|
|
686
|
+
this.containerHeight = Math.max(this.containerHeight, attributes.frame.height)
|
|
687
|
+
return attributes
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
const frame = new math.Rect()
|
|
691
|
+
frame.size = itemSize
|
|
692
|
+
|
|
693
|
+
// 检查所有节点的右边
|
|
694
|
+
for (let index = 0; index < this.attrs.length; index++) {
|
|
695
|
+
const element = this.attrs[index];
|
|
696
|
+
frame.x = element.frame.xMax + this.horizontalSpacing
|
|
697
|
+
frame.y = element.frame.y
|
|
698
|
+
if (frame.xMax <= (this.containerWidth - this.sectionInset.right)) {
|
|
699
|
+
if (this.intersects(frame) == false) {
|
|
700
|
+
let attributes = YXLayoutAttributes.layoutAttributesForCell(indexPath)
|
|
701
|
+
attributes.frame.set(frame)
|
|
702
|
+
this.attrs.push(attributes)
|
|
703
|
+
this.containerHeight = Math.max(this.containerHeight, attributes.frame.yMax - this.offset)
|
|
704
|
+
return attributes
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
// 走到这里表示这块内容区域已经摆不下了,需要换行处理
|
|
710
|
+
return null
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
layout_vertical_complet() {
|
|
714
|
+
|
|
715
|
+
// 反转水平方向 (如果需要的话)
|
|
716
|
+
if (this.reverse & _yx_flow_layout_reverse_mode.HORIZONTAL) {
|
|
717
|
+
this.attrs = this.attrs.reverse()
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
// 调整对齐方式
|
|
721
|
+
if (this.alignment == _yx_flow_layout_alignment.CENTER) {
|
|
722
|
+
for (let index = 0; index < this.attrs.length; index++) {
|
|
723
|
+
const element = this.attrs[index];
|
|
724
|
+
element.frame.y = this.offset + (this.containerHeight - element.frame.height) * 0.5
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
if (this.alignment == _yx_flow_layout_alignment.BACKWARD) {
|
|
728
|
+
for (let index = 0; index < this.attrs.length; index++) {
|
|
729
|
+
const element = this.attrs[index];
|
|
730
|
+
element.frame.y = this.offset + (this.containerHeight - element.frame.height)
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
// 按优先级调整节点位置
|
|
735
|
+
let priority = this.priority
|
|
736
|
+
if (priority == _yx_flow_layout_priority.SIDE && this.attrs.length == 1) {
|
|
737
|
+
priority = this.lastItemPriority
|
|
738
|
+
}
|
|
739
|
+
if (priority == _yx_flow_layout_priority.TOP || priority == _yx_flow_layout_priority.BOTTOM) {
|
|
740
|
+
throw new Error("flow layout priority/lastItemPriority 配置错误: 不支持的优先级配置");
|
|
741
|
+
}
|
|
742
|
+
if (priority == _yx_flow_layout_priority.CENTER) {
|
|
743
|
+
let totalWidth = 0
|
|
744
|
+
for (let index = 0; index < this.attrs.length; index++) {
|
|
745
|
+
const element = this.attrs[index];
|
|
746
|
+
totalWidth += element.frame.width
|
|
747
|
+
}
|
|
748
|
+
totalWidth = totalWidth + (this.attrs.length - 1) * this.horizontalSpacing
|
|
749
|
+
let left = (this.containerWidth - totalWidth) * 0.5
|
|
750
|
+
for (let index = 0; index < this.attrs.length; index++) {
|
|
751
|
+
const element = this.attrs[index];
|
|
752
|
+
element.frame.x = left
|
|
753
|
+
left = element.frame.xMax + this.horizontalSpacing
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
if (priority == _yx_flow_layout_priority.LEFT && this.reverse & _yx_flow_layout_reverse_mode.HORIZONTAL) {
|
|
757
|
+
let left = this.sectionInset.left
|
|
758
|
+
for (let index = 0; index < this.attrs.length; index++) {
|
|
759
|
+
const element = this.attrs[index];
|
|
760
|
+
element.frame.x = left
|
|
761
|
+
left = element.frame.xMax + this.horizontalSpacing
|
|
762
|
+
}
|
|
763
|
+
}
|
|
764
|
+
if (priority == _yx_flow_layout_priority.RIGHT) {
|
|
765
|
+
let totalWidth = 0
|
|
766
|
+
for (let index = 0; index < this.attrs.length; index++) {
|
|
767
|
+
const element = this.attrs[index];
|
|
768
|
+
totalWidth += element.frame.width
|
|
769
|
+
}
|
|
770
|
+
totalWidth = totalWidth + (this.attrs.length - 1) * this.horizontalSpacing
|
|
771
|
+
let left = (this.containerWidth - totalWidth) - this.sectionInset.right
|
|
772
|
+
for (let index = 0; index < this.attrs.length; index++) {
|
|
773
|
+
const element = this.attrs[index];
|
|
774
|
+
element.frame.x = left
|
|
775
|
+
left = element.frame.xMax + this.horizontalSpacing
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
if (priority == _yx_flow_layout_priority.SIDE) {
|
|
779
|
+
let totalWidth = 0
|
|
780
|
+
for (let index = 0; index < this.attrs.length; index++) {
|
|
781
|
+
const element = this.attrs[index];
|
|
782
|
+
totalWidth += element.frame.width
|
|
783
|
+
}
|
|
784
|
+
let horizontalSpacing = (this.containerWidth - this.sectionInset.left - this.sectionInset.right - totalWidth) / (this.attrs.length - 1)
|
|
785
|
+
let offset = this.sectionInset.left
|
|
786
|
+
for (let index = 0; index < this.attrs.length; index++) {
|
|
787
|
+
const element = this.attrs[index];
|
|
788
|
+
element.frame.x = offset
|
|
789
|
+
offset = element.frame.xMax + horizontalSpacing
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
/**
|
|
795
|
+
* 水平方向列表的节点的排列规则
|
|
796
|
+
*/
|
|
797
|
+
layout_horizontal_item(indexPath: YXIndexPath, itemSize: math.Size) {
|
|
798
|
+
if (this.attrs.length <= 0) {
|
|
799
|
+
let attributes = YXLayoutAttributes.layoutAttributesForCell(indexPath)
|
|
800
|
+
attributes.frame.set(this.offset, this.sectionInset.top, itemSize.width, itemSize.height)
|
|
801
|
+
this.attrs.push(attributes)
|
|
802
|
+
this.containerWidth = Math.max(this.containerWidth, attributes.frame.width)
|
|
803
|
+
return attributes
|
|
804
|
+
}
|
|
805
|
+
|
|
806
|
+
const frame = new math.Rect()
|
|
807
|
+
frame.size = itemSize
|
|
808
|
+
|
|
809
|
+
// 检测所有节点的下边
|
|
810
|
+
for (let index = 0; index < this.attrs.length; index++) {
|
|
811
|
+
const element = this.attrs[index];
|
|
812
|
+
frame.x = element.frame.x
|
|
813
|
+
frame.y = element.frame.yMax + this.verticalSpacing
|
|
814
|
+
if (frame.yMax <= (this.containerHeight - this.sectionInset.bottom)) {
|
|
815
|
+
if (this.intersects(frame) == false) {
|
|
816
|
+
let attributes = YXLayoutAttributes.layoutAttributesForCell(indexPath)
|
|
817
|
+
attributes.frame.set(frame)
|
|
818
|
+
this.attrs.push(attributes)
|
|
819
|
+
this.containerWidth = Math.max(this.containerWidth, attributes.frame.xMax - this.offset)
|
|
820
|
+
return attributes
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
}
|
|
824
|
+
|
|
825
|
+
// 走到这里表示这块内容区域已经摆不下了
|
|
826
|
+
return null
|
|
827
|
+
}
|
|
828
|
+
|
|
829
|
+
layout_horizontal_complet() {
|
|
830
|
+
|
|
831
|
+
// 反转垂直方向 (如果需要的话)
|
|
832
|
+
if (this.reverse & _yx_flow_layout_reverse_mode.VERTICAL) {
|
|
833
|
+
this.attrs = this.attrs.reverse()
|
|
834
|
+
}
|
|
835
|
+
|
|
836
|
+
// 调整对齐方式
|
|
837
|
+
if (this.alignment == _yx_flow_layout_alignment.CENTER) {
|
|
838
|
+
for (let index = 0; index < this.attrs.length; index++) {
|
|
839
|
+
const element = this.attrs[index];
|
|
840
|
+
element.frame.x = this.offset + (this.containerWidth - element.frame.width) * 0.5
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
if (this.alignment == _yx_flow_layout_alignment.BACKWARD) {
|
|
844
|
+
for (let index = 0; index < this.attrs.length; index++) {
|
|
845
|
+
const element = this.attrs[index];
|
|
846
|
+
element.frame.x = this.offset + (this.containerWidth - element.frame.width)
|
|
847
|
+
}
|
|
848
|
+
}
|
|
849
|
+
|
|
850
|
+
// 按优先级调整节点位置
|
|
851
|
+
let priority = this.priority
|
|
852
|
+
if (priority == _yx_flow_layout_priority.SIDE && this.attrs.length == 1) {
|
|
853
|
+
priority = this.lastItemPriority
|
|
854
|
+
}
|
|
855
|
+
if (priority == _yx_flow_layout_priority.LEFT || priority == _yx_flow_layout_priority.RIGHT) {
|
|
856
|
+
throw new Error("flow layout priority/lastItemPriority 配置错误: 不支持的优先级配置");
|
|
857
|
+
}
|
|
858
|
+
if (priority == _yx_flow_layout_priority.CENTER) {
|
|
859
|
+
let totalHeight = 0
|
|
860
|
+
for (let index = 0; index < this.attrs.length; index++) {
|
|
861
|
+
const element = this.attrs[index];
|
|
862
|
+
totalHeight += element.frame.height
|
|
863
|
+
}
|
|
864
|
+
totalHeight = totalHeight + (this.attrs.length - 1) * this.verticalSpacing
|
|
865
|
+
let top = (this.containerHeight - totalHeight) * 0.5
|
|
866
|
+
for (let index = 0; index < this.attrs.length; index++) {
|
|
867
|
+
const element = this.attrs[index];
|
|
868
|
+
element.frame.y = top
|
|
869
|
+
top = element.frame.yMax + this.verticalSpacing
|
|
870
|
+
}
|
|
871
|
+
}
|
|
872
|
+
if (priority == _yx_flow_layout_priority.TOP && this.reverse & _yx_flow_layout_reverse_mode.VERTICAL) {
|
|
873
|
+
let top = this.sectionInset.top
|
|
874
|
+
for (let index = 0; index < this.attrs.length; index++) {
|
|
875
|
+
const element = this.attrs[index];
|
|
876
|
+
element.frame.y = top
|
|
877
|
+
top = element.frame.yMax + this.verticalSpacing
|
|
878
|
+
}
|
|
879
|
+
}
|
|
880
|
+
if (priority == _yx_flow_layout_priority.BOTTOM) {
|
|
881
|
+
let totalHeight = 0
|
|
882
|
+
for (let index = 0; index < this.attrs.length; index++) {
|
|
883
|
+
const element = this.attrs[index];
|
|
884
|
+
totalHeight += element.frame.height
|
|
885
|
+
}
|
|
886
|
+
totalHeight = totalHeight + (this.attrs.length - 1) * this.verticalSpacing
|
|
887
|
+
let top = (this.containerHeight - totalHeight) - this.sectionInset.bottom
|
|
888
|
+
for (let index = 0; index < this.attrs.length; index++) {
|
|
889
|
+
const element = this.attrs[index];
|
|
890
|
+
element.frame.y = top
|
|
891
|
+
top = element.frame.yMax + this.verticalSpacing
|
|
892
|
+
}
|
|
893
|
+
}
|
|
894
|
+
if (priority == _yx_flow_layout_priority.SIDE) {
|
|
895
|
+
let totalHeight = 0
|
|
896
|
+
for (let index = 0; index < this.attrs.length; index++) {
|
|
897
|
+
const element = this.attrs[index];
|
|
898
|
+
totalHeight += element.frame.height
|
|
899
|
+
}
|
|
900
|
+
let verticalSpacing = (this.containerHeight - this.sectionInset.top - this.sectionInset.bottom - totalHeight) / (this.attrs.length - 1)
|
|
901
|
+
let offset = this.sectionInset.top
|
|
902
|
+
for (let index = 0; index < this.attrs.length; index++) {
|
|
903
|
+
const element = this.attrs[index];
|
|
904
|
+
element.frame.y = offset
|
|
905
|
+
offset = element.frame.yMax + verticalSpacing
|
|
906
|
+
}
|
|
907
|
+
}
|
|
908
|
+
}
|
|
909
|
+
}
|