@shijiu/jsview-vue 2.0.1021 → 2.0.1073
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/package.json +4 -3
- package/utils/JsViewEngineWidget/CheckType.js +82 -0
- package/utils/JsViewEngineWidget/MetroWidget/AnimationManager.ts +72 -0
- package/utils/JsViewEngineWidget/MetroWidget/Const.ts +24 -0
- package/utils/JsViewEngineWidget/MetroWidget/ListWidget.vue +295 -0
- package/utils/JsViewEngineWidget/MetroWidget/MetroWidget.vue +110 -1651
- package/utils/JsViewEngineWidget/MetroWidget/MetroWidgetSetup.js +1867 -0
- package/utils/JsViewEngineWidget/MetroWidget/PageUpdater.ts +111 -0
- package/utils/JsViewEngineWidget/MetroWidget/RenderItem.ts +153 -0
- package/utils/JsViewEngineWidget/MetroWidget/VisibleInfo.ts +43 -0
- package/utils/JsViewEngineWidget/MetroWidget/WidgetRectInfo.ts +49 -0
- package/utils/JsViewEngineWidget/TemplateParser/CommonMetroTemplate.ts +1424 -0
- package/utils/JsViewEngineWidget/TemplateParser/Fence.ts +135 -0
- package/utils/JsViewEngineWidget/TemplateParser/ListMetroTemplate.ts +177 -0
- package/utils/JsViewEngineWidget/TemplateParser/MetroTemplate.ts +334 -0
- package/utils/JsViewEngineWidget/TemplateParser/TemplateItemAdder.ts +147 -0
- package/utils/JsViewEngineWidget/TemplateParser/index.ts +4 -0
- package/utils/JsViewEngineWidget/{WidgetCommon.js → WidgetCommon.ts} +64 -71
- package/utils/JsViewEngineWidget/index.js +2 -1
- package/utils/JsViewPlugin/JsvAudio/AudioProxy.js +26 -1
- package/utils/JsViewPlugin/JsvAudio/JsvAudio.vue +120 -133
- package/utils/JsViewPlugin/JsvAudio/JsvAudioBrowser.vue +11 -7
- package/utils/JsViewPlugin/JsvPlayer/GetVersion.js +1 -1
- package/utils/JsViewPlugin/JsvPlayer/JsvPlayerBrowser.vue +379 -41
- package/utils/JsViewPlugin/JsvPlayer/version.mjs +5 -5
- package/utils/JsViewVueTools/JsvHashHistory.js +2 -1
- package/utils/JsViewVueWidget/JsvRadarChart.vue +220 -0
- package/utils/JsViewVueWidget/JsvSystemAudio.vue +76 -44
- package/utils/JsViewVueWidget/index.js +1 -0
- package/utils/JsViewEngineWidget/MetroWidget/Const.js +0 -11
- package/utils/JsViewEngineWidget/MetroWidget/PageUpdater.js +0 -136
- package/utils/JsViewEngineWidget/MetroWidget/ToolFunctions.js +0 -18
- package/utils/JsViewEngineWidget/TemplateParser.js +0 -2004
|
@@ -0,0 +1,1867 @@
|
|
|
1
|
+
import {
|
|
2
|
+
reactive,
|
|
3
|
+
onMounted,
|
|
4
|
+
onBeforeUnmount,
|
|
5
|
+
onUpdated,
|
|
6
|
+
toRaw,
|
|
7
|
+
nextTick,
|
|
8
|
+
} from "vue";
|
|
9
|
+
import { Forge } from "@shijiu/jsview/dom/jsv-forge-define";
|
|
10
|
+
import {
|
|
11
|
+
CommonMetroTemplate,
|
|
12
|
+
ListMetroTemplate,
|
|
13
|
+
TemplateItemAdder,
|
|
14
|
+
} from "../TemplateParser/index";
|
|
15
|
+
import { PageUpdater } from "./PageUpdater";
|
|
16
|
+
import { SingleRangeModel } from "../RangeModel";
|
|
17
|
+
import { METRO_WIDGET_CONST } from "./Const";
|
|
18
|
+
import {
|
|
19
|
+
EdgeDirection,
|
|
20
|
+
VERTICAL,
|
|
21
|
+
HORIZONTAL,
|
|
22
|
+
SlideSetting,
|
|
23
|
+
} from "../WidgetCommon";
|
|
24
|
+
import { RenderItem } from "./RenderItem";
|
|
25
|
+
import { VisibleInfo } from "./VisibleInfo";
|
|
26
|
+
import { AnimationManager, AnimationTools } from "./AnimationManager";
|
|
27
|
+
import { WidgetRectInfo } from "./WidgetRectInfo";
|
|
28
|
+
import { checkType } from "../CheckType";
|
|
29
|
+
|
|
30
|
+
const TAG = "MetroWidget";
|
|
31
|
+
|
|
32
|
+
const _getMetroTemplate = function (
|
|
33
|
+
widgetRectInfo,
|
|
34
|
+
direction,
|
|
35
|
+
support_history_path,
|
|
36
|
+
layout_type,
|
|
37
|
+
mode
|
|
38
|
+
) {
|
|
39
|
+
let page_size;
|
|
40
|
+
let line_max;
|
|
41
|
+
if (direction === VERTICAL) {
|
|
42
|
+
line_max = widgetRectInfo.contentWidth;
|
|
43
|
+
page_size = widgetRectInfo.contentHeight;
|
|
44
|
+
} else {
|
|
45
|
+
line_max = widgetRectInfo.contentHeight;
|
|
46
|
+
page_size = widgetRectInfo.contentWidth;
|
|
47
|
+
}
|
|
48
|
+
let metroWidget;
|
|
49
|
+
switch (mode) {
|
|
50
|
+
case "list":
|
|
51
|
+
metroWidget = new ListMetroTemplate(
|
|
52
|
+
direction,
|
|
53
|
+
line_max,
|
|
54
|
+
page_size,
|
|
55
|
+
layout_type,
|
|
56
|
+
support_history_path
|
|
57
|
+
);
|
|
58
|
+
break;
|
|
59
|
+
default:
|
|
60
|
+
metroWidget = new CommonMetroTemplate(
|
|
61
|
+
direction,
|
|
62
|
+
line_max,
|
|
63
|
+
page_size,
|
|
64
|
+
layout_type,
|
|
65
|
+
support_history_path
|
|
66
|
+
);
|
|
67
|
+
break;
|
|
68
|
+
}
|
|
69
|
+
return metroWidget;
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
export const setup = (
|
|
73
|
+
props,
|
|
74
|
+
touchContainerW,
|
|
75
|
+
touchContainerH,
|
|
76
|
+
itemRender,
|
|
77
|
+
locateDiv,
|
|
78
|
+
renderData,
|
|
79
|
+
slideDiv,
|
|
80
|
+
slideDivLeft,
|
|
81
|
+
slideDivTop,
|
|
82
|
+
itemResizeSlideDiv,
|
|
83
|
+
itemResizeSlideLeft,
|
|
84
|
+
itemResizeSlideTop,
|
|
85
|
+
focusNode,
|
|
86
|
+
pageUpdateToken,
|
|
87
|
+
templateMode) => {
|
|
88
|
+
let widgetRectInfo = new WidgetRectInfo(props.width, props.height, props.padding);
|
|
89
|
+
let metroTemplate = _getMetroTemplate(
|
|
90
|
+
widgetRectInfo,
|
|
91
|
+
props.direction,
|
|
92
|
+
props.supportHistoryPath,
|
|
93
|
+
props.layoutType,
|
|
94
|
+
templateMode
|
|
95
|
+
);
|
|
96
|
+
let innerData = [];
|
|
97
|
+
let dataList = [];
|
|
98
|
+
let pageUpdater = null;
|
|
99
|
+
let enterFocusId = -1;
|
|
100
|
+
let enterFocusRect = null;
|
|
101
|
+
let focusId = 0;
|
|
102
|
+
let preFocusId = -1;
|
|
103
|
+
let preEdgeRect = null;
|
|
104
|
+
let isFocus = false;
|
|
105
|
+
let touchListener = null;
|
|
106
|
+
let slidePile = null;
|
|
107
|
+
let dragDirection = Forge.DragSetting.DIRECTION_HORIZONTAL;
|
|
108
|
+
let vertical = props.direction == VERTICAL;
|
|
109
|
+
let preAnchorItemIndex = -1;
|
|
110
|
+
let preSeamlessSlideDirection = 1;
|
|
111
|
+
let templateItemAdder = null;
|
|
112
|
+
let permanentItemList = [];
|
|
113
|
+
let preUpdateVisibleStart = 0;
|
|
114
|
+
let mounted = false;
|
|
115
|
+
let pageRange = vertical ? props.height : props.width;
|
|
116
|
+
let slideLock = false;
|
|
117
|
+
let childSlideEventLock = false;
|
|
118
|
+
let onKeyDownLock = false;
|
|
119
|
+
let visibleInfo = new VisibleInfo();
|
|
120
|
+
|
|
121
|
+
const DEFAULT_ANIMATION_DURATION = 200;
|
|
122
|
+
const animationManager = new AnimationManager();
|
|
123
|
+
|
|
124
|
+
const updateDivPosition =
|
|
125
|
+
(divRef, leftRef, topRef, onStart, onEnd) => (x, y, animInfo) => {
|
|
126
|
+
if (toRaw(divRef.value)) {
|
|
127
|
+
const pre_left = leftRef.value;
|
|
128
|
+
const pre_top = topRef.value;
|
|
129
|
+
leftRef.value = x;
|
|
130
|
+
topRef.value = y;
|
|
131
|
+
|
|
132
|
+
if (animInfo) {
|
|
133
|
+
let startCallback = () => {
|
|
134
|
+
onStart?.();
|
|
135
|
+
animInfo?.onStart?.();
|
|
136
|
+
};
|
|
137
|
+
let endCallback = (animDone) => {
|
|
138
|
+
onEnd?.(animDone);
|
|
139
|
+
animInfo?.onEnd?.(animDone);
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
const delta_x = Math.round(pre_left - x);
|
|
143
|
+
const delta_y = Math.round(pre_top - y);
|
|
144
|
+
|
|
145
|
+
const animNode = AnimationTools.getDivSlideAnim(
|
|
146
|
+
toRaw(divRef.value),
|
|
147
|
+
delta_x,
|
|
148
|
+
delta_y,
|
|
149
|
+
0,
|
|
150
|
+
0,
|
|
151
|
+
{
|
|
152
|
+
easing: animInfo.easing,
|
|
153
|
+
duration: animInfo.duration,
|
|
154
|
+
speed: animInfo.speed,
|
|
155
|
+
onStart: startCallback,
|
|
156
|
+
onEnd: endCallback,
|
|
157
|
+
}
|
|
158
|
+
);
|
|
159
|
+
animationManager.tryStartAnim(Forge.sFrameCount.count, animNode);
|
|
160
|
+
} else {
|
|
161
|
+
onStart?.();
|
|
162
|
+
onEnd?.();
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
const updateSlideDiv = updateDivPosition(slideDiv, slideDivLeft, slideDivTop);
|
|
168
|
+
|
|
169
|
+
const _slideTo = (target, animObj) => {
|
|
170
|
+
if (vertical) {
|
|
171
|
+
updateSlideDiv(0, -target - itemResizeSlideTop.value, animObj);
|
|
172
|
+
} else {
|
|
173
|
+
updateSlideDiv(-target - itemResizeSlideLeft.value, 0, animObj);
|
|
174
|
+
}
|
|
175
|
+
_onScroll();
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
const updateItemResizeSlideDiv = updateDivPosition(
|
|
179
|
+
itemResizeSlideDiv,
|
|
180
|
+
itemResizeSlideLeft,
|
|
181
|
+
itemResizeSlideTop
|
|
182
|
+
);
|
|
183
|
+
|
|
184
|
+
let itemMovingInfo = null;
|
|
185
|
+
|
|
186
|
+
let callFocusAfterUpdate = false;
|
|
187
|
+
|
|
188
|
+
//methods
|
|
189
|
+
const _onFocusChange = (id) => {
|
|
190
|
+
props.onFocusChange?.(id);
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
// query functions
|
|
194
|
+
const _getCurrentId = () => {
|
|
195
|
+
return {
|
|
196
|
+
id: focusId,
|
|
197
|
+
index: id2Index(focusId),
|
|
198
|
+
};
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
const _getPosition = (index) => {
|
|
202
|
+
let templateInfo = getItemByIndex(index).templateInfo;
|
|
203
|
+
let x_offset = vertical ? 0 : -visibleInfo.start;
|
|
204
|
+
let y_offset = vertical ? -visibleInfo.start : 0;
|
|
205
|
+
return {
|
|
206
|
+
left: templateInfo.left + x_offset,
|
|
207
|
+
top: templateInfo.top + y_offset,
|
|
208
|
+
width: templateInfo.width,
|
|
209
|
+
height: templateInfo.height,
|
|
210
|
+
};
|
|
211
|
+
};
|
|
212
|
+
const _getTemplatePosition = (index) => {
|
|
213
|
+
let templateInfo = getItemByIndex(index).templateInfo;
|
|
214
|
+
return {
|
|
215
|
+
left: templateInfo.left,
|
|
216
|
+
top: templateInfo.top,
|
|
217
|
+
width: templateInfo.width,
|
|
218
|
+
height: templateInfo.height,
|
|
219
|
+
};
|
|
220
|
+
};
|
|
221
|
+
|
|
222
|
+
const _dispatchEvent = (event) => {
|
|
223
|
+
console.error("dispatchEvent is deprecated and will be removed soon. Use MetroWidget exported method instead.")
|
|
224
|
+
switch (event.type) {
|
|
225
|
+
case Dispatcher.Type.setEnterFocusId:
|
|
226
|
+
setEnterFocusId(event.data);
|
|
227
|
+
break;
|
|
228
|
+
case Dispatcher.Type.setEnterFocusRect:
|
|
229
|
+
setEnterFocusRect(event.data);
|
|
230
|
+
break;
|
|
231
|
+
case Dispatcher.Type.updateItem:
|
|
232
|
+
break;
|
|
233
|
+
case Dispatcher.Type.slideToItem:
|
|
234
|
+
if (event.data) {
|
|
235
|
+
slideToItem(event.data?.id, event.data?.doAnim);
|
|
236
|
+
}
|
|
237
|
+
break;
|
|
238
|
+
case Dispatcher.Type.setFocusId:
|
|
239
|
+
setFocusId(event.data?.id, event.data?.needSlide, event.data?.doAnim);
|
|
240
|
+
break;
|
|
241
|
+
default:
|
|
242
|
+
break;
|
|
243
|
+
}
|
|
244
|
+
};
|
|
245
|
+
|
|
246
|
+
const id2Index = (id) => {
|
|
247
|
+
return metroTemplate.id2Index(id);
|
|
248
|
+
};
|
|
249
|
+
|
|
250
|
+
const index2Id = (index) => {
|
|
251
|
+
return metroTemplate.index2Id(index);
|
|
252
|
+
};
|
|
253
|
+
|
|
254
|
+
const getItemByIndex = (index) => {
|
|
255
|
+
return innerData[index];
|
|
256
|
+
};
|
|
257
|
+
|
|
258
|
+
const getItemById = (id) => {
|
|
259
|
+
return innerData[id2Index(id)];
|
|
260
|
+
};
|
|
261
|
+
|
|
262
|
+
const getNextItem = (anchorId, vDirection, hDirection, moveType) => {
|
|
263
|
+
const nextItem = metroTemplate.getNextItem(
|
|
264
|
+
anchorId,
|
|
265
|
+
vDirection,
|
|
266
|
+
hDirection,
|
|
267
|
+
moveType
|
|
268
|
+
);
|
|
269
|
+
if (nextItem) {
|
|
270
|
+
return innerData[nextItem.index];
|
|
271
|
+
} else {
|
|
272
|
+
return null;
|
|
273
|
+
}
|
|
274
|
+
};
|
|
275
|
+
|
|
276
|
+
const setItemZIndex = (item, z_index, is_focus) => {
|
|
277
|
+
if (item) {
|
|
278
|
+
let i = z_index;
|
|
279
|
+
if (is_focus && item.itemConfig.focusZIndex >= 0) {
|
|
280
|
+
i = item.itemConfig.focusZIndex;
|
|
281
|
+
} else if (item.itemConfig.normalZIndex >= 0) {
|
|
282
|
+
i = item.itemConfig.normalZIndex;
|
|
283
|
+
}
|
|
284
|
+
item.renderStyle.zIndex = i;
|
|
285
|
+
}
|
|
286
|
+
};
|
|
287
|
+
|
|
288
|
+
const onItemClick = (item) => {
|
|
289
|
+
if (!item) { return };
|
|
290
|
+
if (isFocus) {
|
|
291
|
+
item.onClick();
|
|
292
|
+
}
|
|
293
|
+
};
|
|
294
|
+
|
|
295
|
+
const onItemBlur = (blurItem) => {
|
|
296
|
+
if (!blurItem) return;
|
|
297
|
+
setItemZIndex(blurItem, 0, false);
|
|
298
|
+
if (isFocus) {
|
|
299
|
+
blurItem.onBlur();
|
|
300
|
+
}
|
|
301
|
+
};
|
|
302
|
+
|
|
303
|
+
const onItemFocus = (focusItem, rect) => {
|
|
304
|
+
if (!focusItem) return;
|
|
305
|
+
setItemZIndex(focusItem, innerData.length, true);
|
|
306
|
+
if (isFocus) {
|
|
307
|
+
_itemOnFocusSideEffect(focusItem, rect);
|
|
308
|
+
const called = focusItem.onFocus(rect);
|
|
309
|
+
if (!called) {
|
|
310
|
+
callFocusAfterUpdate = true;
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
};
|
|
314
|
+
|
|
315
|
+
const setFocusId = (id, needSlide = true, doAnim = false, extraSetting) => {
|
|
316
|
+
if (id == focusId) {
|
|
317
|
+
return;
|
|
318
|
+
}
|
|
319
|
+
templateItemAdder.tryAddItemById(id);
|
|
320
|
+
let next_focus_item = getItemById(id);
|
|
321
|
+
if (next_focus_item) {
|
|
322
|
+
preFocusId = focusId;
|
|
323
|
+
const preFocusItem = getItemById(preFocusId);
|
|
324
|
+
const nextTemplateInfo = next_focus_item.templateInfo;
|
|
325
|
+
focusId = nextTemplateInfo.id;
|
|
326
|
+
onItemBlur(preFocusItem);
|
|
327
|
+
onItemFocus(next_focus_item, preEdgeRect);
|
|
328
|
+
if (needSlide) {
|
|
329
|
+
slideToItem(id2Index(id), doAnim);
|
|
330
|
+
}
|
|
331
|
+
let unlock = null;
|
|
332
|
+
if (extraSetting) {
|
|
333
|
+
if (extraSetting.lockChildSlideEvent) {
|
|
334
|
+
unlock = lock(METRO_WIDGET_CONST.CHILD_SLIDE_EVENT);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
const curTemplateInfo = getItemById(focusId).templateInfo;
|
|
339
|
+
|
|
340
|
+
let x_off_set = curTemplateInfo.left - nextTemplateInfo.left;
|
|
341
|
+
let y_off_set = curTemplateInfo.top - nextTemplateInfo.top;
|
|
342
|
+
preEdgeRect = {
|
|
343
|
+
direction: null,
|
|
344
|
+
rect: {
|
|
345
|
+
x: x_off_set,
|
|
346
|
+
y: y_off_set,
|
|
347
|
+
width: curTemplateInfo.width,
|
|
348
|
+
height: curTemplateInfo.height,
|
|
349
|
+
},
|
|
350
|
+
};
|
|
351
|
+
unlock?.();
|
|
352
|
+
}
|
|
353
|
+
};
|
|
354
|
+
|
|
355
|
+
const lock = (type) => {
|
|
356
|
+
const unlocker = [];
|
|
357
|
+
if (type & METRO_WIDGET_CONST.SLIDE) {
|
|
358
|
+
slideLock = true;
|
|
359
|
+
unlocker.push(() => {
|
|
360
|
+
slideLock = false;
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
if (type & METRO_WIDGET_CONST.CHILD_SLIDE_EVENT) {
|
|
364
|
+
childSlideEventLock = true;
|
|
365
|
+
unlocker.push(() => {
|
|
366
|
+
childSlideEventLock = false;
|
|
367
|
+
});
|
|
368
|
+
}
|
|
369
|
+
if (type & METRO_WIDGET_CONST.ON_KEY_DOWN) {
|
|
370
|
+
onKeyDownLock = true;
|
|
371
|
+
unlocker.push(() => {
|
|
372
|
+
onKeyDownLock = false;
|
|
373
|
+
});
|
|
374
|
+
}
|
|
375
|
+
return () => {
|
|
376
|
+
unlocker.map((item) => {
|
|
377
|
+
item();
|
|
378
|
+
});
|
|
379
|
+
};
|
|
380
|
+
};
|
|
381
|
+
|
|
382
|
+
const unlock = (type) => {
|
|
383
|
+
if (type & METRO_WIDGET_CONST.SLIDE) {
|
|
384
|
+
slideLock = true;
|
|
385
|
+
}
|
|
386
|
+
if (type & METRO_WIDGET_CONST.CHILD_SLIDE_EVENT) {
|
|
387
|
+
childSlideEventLock = true;
|
|
388
|
+
}
|
|
389
|
+
if (type & METRO_WIDGET_CONST.ON_KEY_DOWN) {
|
|
390
|
+
onKeyDownLock = true;
|
|
391
|
+
}
|
|
392
|
+
};
|
|
393
|
+
|
|
394
|
+
const getFocusBlockRef = () => {
|
|
395
|
+
return toRaw(focusNode.value);
|
|
396
|
+
};
|
|
397
|
+
|
|
398
|
+
const setEnterFocusId = (id) => {
|
|
399
|
+
templateItemAdder.tryAddItemById(id);
|
|
400
|
+
enterFocusId = id;
|
|
401
|
+
};
|
|
402
|
+
|
|
403
|
+
const setEnterFocusRect = (rect) => {
|
|
404
|
+
enterFocusRect = rect;
|
|
405
|
+
};
|
|
406
|
+
|
|
407
|
+
const slideTo = (position, doAnim) => {
|
|
408
|
+
templateItemAdder.tryAddItemByPosition(position);
|
|
409
|
+
if (
|
|
410
|
+
typeof position !== "undefined" &&
|
|
411
|
+
position != null &&
|
|
412
|
+
visibleInfo.start !== position
|
|
413
|
+
) {
|
|
414
|
+
visibleInfo.start = position;
|
|
415
|
+
|
|
416
|
+
const updater = pageUpdater.update(
|
|
417
|
+
metroTemplate,
|
|
418
|
+
visibleInfo.startWithPadding,
|
|
419
|
+
visibleInfo.endWithPadding,
|
|
420
|
+
focusId,
|
|
421
|
+
false,
|
|
422
|
+
permanentItemList
|
|
423
|
+
);
|
|
424
|
+
|
|
425
|
+
let animObj = null;
|
|
426
|
+
if (doAnim) {
|
|
427
|
+
animObj = {
|
|
428
|
+
easing: props.slideSetting.Easing,
|
|
429
|
+
onStart: null,
|
|
430
|
+
speed: props.slideSetting.Speed,
|
|
431
|
+
onEnd: () => {
|
|
432
|
+
updater.apply();
|
|
433
|
+
},
|
|
434
|
+
};
|
|
435
|
+
pageUpdater.applyTmp();
|
|
436
|
+
} else {
|
|
437
|
+
pageUpdater.apply();
|
|
438
|
+
}
|
|
439
|
+
_slideTo(visibleInfo.start, animObj);
|
|
440
|
+
}
|
|
441
|
+
};
|
|
442
|
+
|
|
443
|
+
const slideToItem = (index, doAnim) => {
|
|
444
|
+
templateItemAdder.tryAddItemByIndex(index);
|
|
445
|
+
const targetItem = getItemByIndex(index);
|
|
446
|
+
if (targetItem) {
|
|
447
|
+
const direction = index - preAnchorItemIndex > 0 ? 1 : -1;
|
|
448
|
+
const visible_start = _calculateVisibleStart(targetItem.templateInfo, direction);
|
|
449
|
+
slideTo(visible_start, doAnim);
|
|
450
|
+
}
|
|
451
|
+
};
|
|
452
|
+
|
|
453
|
+
const refreshData = (force_update) => {
|
|
454
|
+
//由于data不支持reactive, 因此数据的更新只通过provideData
|
|
455
|
+
if (!props.provideData) {
|
|
456
|
+
console.error("refreshData: provideData is null.");
|
|
457
|
+
return;
|
|
458
|
+
}
|
|
459
|
+
let _force_update = force_update;
|
|
460
|
+
if (metroTemplate.size === 0) {
|
|
461
|
+
_force_update = true;
|
|
462
|
+
}
|
|
463
|
+
let new_list = toRaw(props.provideData());
|
|
464
|
+
let needSlide = false;
|
|
465
|
+
if (focusId >= new_list.length) {
|
|
466
|
+
focusId = 0;
|
|
467
|
+
preFocusId = -1;
|
|
468
|
+
if (visibleInfo.start !== 0) {
|
|
469
|
+
visibleInfo.start = 0;
|
|
470
|
+
needSlide = true;
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
let new_index = 0;
|
|
474
|
+
if (!_force_update) {
|
|
475
|
+
for (new_index = 0; new_index < new_list.length; ++new_index) {
|
|
476
|
+
let already_add = false;
|
|
477
|
+
for (let j = 0; j < innerData.length; ++j) {
|
|
478
|
+
if (new_list[new_index] === innerData[j].customerData) {
|
|
479
|
+
already_add = true;
|
|
480
|
+
break;
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
if (!already_add) {
|
|
484
|
+
break;
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
let need_update_content = false;
|
|
489
|
+
if (!_force_update && new_index === metroTemplate.size) {
|
|
490
|
+
//原始数据都在
|
|
491
|
+
if (new_index !== new_list.length) {
|
|
492
|
+
//增加数据
|
|
493
|
+
need_update_content = true;
|
|
494
|
+
templateItemAdder.updateData(new_list);
|
|
495
|
+
} else {
|
|
496
|
+
//数据没变
|
|
497
|
+
}
|
|
498
|
+
} else {
|
|
499
|
+
pageUpdateToken.value++;
|
|
500
|
+
//数据更改
|
|
501
|
+
permanentItemList = [];
|
|
502
|
+
need_update_content = true;
|
|
503
|
+
metroTemplate = _getMetroTemplate(
|
|
504
|
+
widgetRectInfo,
|
|
505
|
+
props.direction,
|
|
506
|
+
props.supportHistoryPath,
|
|
507
|
+
props.layoutType,
|
|
508
|
+
templateMode
|
|
509
|
+
);
|
|
510
|
+
innerData = [];
|
|
511
|
+
dataList = new_list;
|
|
512
|
+
templateItemAdder = new TemplateItemAdder(
|
|
513
|
+
metroTemplate,
|
|
514
|
+
dataList,
|
|
515
|
+
props.measures,
|
|
516
|
+
pageRange,
|
|
517
|
+
_onTemplateAdd,
|
|
518
|
+
props.name
|
|
519
|
+
);
|
|
520
|
+
}
|
|
521
|
+
if (need_update_content) {
|
|
522
|
+
if (props.onScroll) {
|
|
523
|
+
templateItemAdder.tryAddItemByIndex(dataList.length - 1);
|
|
524
|
+
} else {
|
|
525
|
+
templateItemAdder.tryAddItemById(focusId);
|
|
526
|
+
}
|
|
527
|
+
let lastTemplateInfo = getItemByIndex(metroTemplate.size - 1)?.templateInfo;
|
|
528
|
+
touchListener = _getTouchListener();
|
|
529
|
+
touchContainerW.value = vertical
|
|
530
|
+
? props.width
|
|
531
|
+
: lastTemplateInfo
|
|
532
|
+
? lastTemplateInfo.left + lastTemplateInfo.width
|
|
533
|
+
: 0;
|
|
534
|
+
touchContainerH.value = vertical
|
|
535
|
+
? lastTemplateInfo
|
|
536
|
+
? lastTemplateInfo.top + lastTemplateInfo.height
|
|
537
|
+
: 0
|
|
538
|
+
: props.height;
|
|
539
|
+
slidePile = new Forge.RectArea(
|
|
540
|
+
0,
|
|
541
|
+
0,
|
|
542
|
+
widgetRectInfo.contentWidth,
|
|
543
|
+
widgetRectInfo.contentHeight,
|
|
544
|
+
);
|
|
545
|
+
dragDirection =
|
|
546
|
+
vertical
|
|
547
|
+
? Forge.DragSetting.DIRECTION_VERTICAL
|
|
548
|
+
: Forge.DragSetting.DIRECTION_HORIZONTAL;
|
|
549
|
+
}
|
|
550
|
+
const updater = pageUpdater.update(
|
|
551
|
+
metroTemplate,
|
|
552
|
+
visibleInfo.startWithPadding,
|
|
553
|
+
visibleInfo.endWithPadding,
|
|
554
|
+
focusId,
|
|
555
|
+
false,
|
|
556
|
+
permanentItemList
|
|
557
|
+
);
|
|
558
|
+
updater.apply();
|
|
559
|
+
onItemFocus(getItemById(focusId), null);
|
|
560
|
+
if (needSlide) {
|
|
561
|
+
_slideTo(visibleInfo.start, null);
|
|
562
|
+
} else if (need_update_content) {
|
|
563
|
+
_onScroll();
|
|
564
|
+
}
|
|
565
|
+
};
|
|
566
|
+
|
|
567
|
+
const getVisibleItems = () => {
|
|
568
|
+
const [visibleStart, visibleEnd] = metroTemplate.getVisibleItemList(
|
|
569
|
+
visibleInfo.startWithPadding,
|
|
570
|
+
visibleInfo.endWithPadding,
|
|
571
|
+
focusId
|
|
572
|
+
);
|
|
573
|
+
return {
|
|
574
|
+
start: visibleStart,
|
|
575
|
+
end: visibleEnd,
|
|
576
|
+
dataList: dataList.slice(info.visibleStart, info.visibleEnd + 1),
|
|
577
|
+
};
|
|
578
|
+
};
|
|
579
|
+
|
|
580
|
+
const moveFocus = (direction) => {
|
|
581
|
+
if (direction == "left" || direction == 37 || direction == EdgeDirection.left) {
|
|
582
|
+
_moveToNext(-1, 0);
|
|
583
|
+
} else if (direction == "right" || direction == 39 || direction == EdgeDirection.right) {
|
|
584
|
+
_moveToNext(1, 0);
|
|
585
|
+
} else if (direction == "top" || direction == 38 || direction == EdgeDirection.top) {
|
|
586
|
+
_moveToNext(0, -1);
|
|
587
|
+
} else if (direction == "bottom" || direction == 40 || direction == EdgeDirection.bottom) {
|
|
588
|
+
_moveToNext(0, 1);
|
|
589
|
+
} else {
|
|
590
|
+
console.error(TAG, "moveFocus direction is invalid.", direction);
|
|
591
|
+
}
|
|
592
|
+
};
|
|
593
|
+
|
|
594
|
+
const getCustomerDataSize = () => {
|
|
595
|
+
return dataList.length;
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
const exportObject = {
|
|
599
|
+
lock,
|
|
600
|
+
unlock,
|
|
601
|
+
slideTo,
|
|
602
|
+
setFocusId,
|
|
603
|
+
getFocusBlockRef,
|
|
604
|
+
setEnterFocusId,
|
|
605
|
+
setEnterFocusRect,
|
|
606
|
+
slideToItem,
|
|
607
|
+
refreshData,
|
|
608
|
+
_dispatchEvent,
|
|
609
|
+
getVisibleItems,
|
|
610
|
+
moveFocus,
|
|
611
|
+
getCustomerDataSize,
|
|
612
|
+
};
|
|
613
|
+
|
|
614
|
+
const _calculateNearestItemByRect = (visibleSet, enter_rect_info) => {
|
|
615
|
+
let edge_direction = enter_rect_info.direction;
|
|
616
|
+
let rect = enter_rect_info.rect;
|
|
617
|
+
var direction = "";
|
|
618
|
+
var point = { x: 0, y: 0 };
|
|
619
|
+
switch (edge_direction) {
|
|
620
|
+
case EdgeDirection.left:
|
|
621
|
+
direction = "left";
|
|
622
|
+
point.x = rect.x;
|
|
623
|
+
point.y = rect.y + rect.height / 4;
|
|
624
|
+
break;
|
|
625
|
+
case EdgeDirection.right:
|
|
626
|
+
direction = "right";
|
|
627
|
+
point.x = rect.x + rect.width;
|
|
628
|
+
point.y = rect.y + rect.height / 4;
|
|
629
|
+
break;
|
|
630
|
+
case EdgeDirection.top:
|
|
631
|
+
direction = "up";
|
|
632
|
+
point.x = rect.x + rect.width / 4;
|
|
633
|
+
point.y = rect.y;
|
|
634
|
+
break;
|
|
635
|
+
case EdgeDirection.bottom:
|
|
636
|
+
direction = "down";
|
|
637
|
+
point.x = rect.x + rect.width / 4;
|
|
638
|
+
point.y = rect.y + rect.height;
|
|
639
|
+
break;
|
|
640
|
+
default:
|
|
641
|
+
break;
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
var src_x_range = new SingleRangeModel(point.x, point.x);
|
|
645
|
+
var src_y_range = new SingleRangeModel(point.y, point.y);
|
|
646
|
+
|
|
647
|
+
var min_distance_item = null;
|
|
648
|
+
var min_distance = -1;
|
|
649
|
+
var min_direction_weighted = 0;
|
|
650
|
+
var distance = 0;
|
|
651
|
+
var direction_weighted = 0; // 根据进入方向决定的权值,用于保证
|
|
652
|
+
|
|
653
|
+
let key_pos = vertical ? "top" : "left";
|
|
654
|
+
let key_width = vertical ? "height" : "width";
|
|
655
|
+
|
|
656
|
+
for (let index of visibleSet) {
|
|
657
|
+
let itemTemplateInfo = getItemByIndex(index).templateInfo;
|
|
658
|
+
if (!itemTemplateInfo.focusable) continue;
|
|
659
|
+
let full_show =
|
|
660
|
+
itemTemplateInfo[key_pos] >= visibleInfo.start &&
|
|
661
|
+
itemTemplateInfo[key_pos] + itemTemplateInfo[key_width] - 1 <=
|
|
662
|
+
visibleInfo.end;
|
|
663
|
+
if (full_show) {
|
|
664
|
+
let x_pos =
|
|
665
|
+
vertical
|
|
666
|
+
? itemTemplateInfo.left
|
|
667
|
+
: itemTemplateInfo.left - visibleInfo.start;
|
|
668
|
+
let y_pos =
|
|
669
|
+
vertical
|
|
670
|
+
? itemTemplateInfo.top - visibleInfo.start
|
|
671
|
+
: itemTemplateInfo.top;
|
|
672
|
+
var target_x_range = new SingleRangeModel(
|
|
673
|
+
x_pos,
|
|
674
|
+
x_pos + itemTemplateInfo.width - 1
|
|
675
|
+
);
|
|
676
|
+
var target_y_range = new SingleRangeModel(
|
|
677
|
+
y_pos,
|
|
678
|
+
y_pos + itemTemplateInfo.height - 1
|
|
679
|
+
);
|
|
680
|
+
switch (direction) {
|
|
681
|
+
case "left":
|
|
682
|
+
if (point.x < x_pos + itemTemplateInfo.width - 1) {
|
|
683
|
+
// 这个点在item左侧,不可能左移到item
|
|
684
|
+
continue;
|
|
685
|
+
}
|
|
686
|
+
if (point.y < y_pos) {
|
|
687
|
+
//1.该点在其上,计算point和item右上角的距离
|
|
688
|
+
distance =
|
|
689
|
+
Math.pow(point.x - (x_pos + itemTemplateInfo.width - 1), 2) +
|
|
690
|
+
Math.pow(y_pos - point.y, 2);
|
|
691
|
+
} else if (src_y_range.IsInterAct(target_y_range)) {
|
|
692
|
+
//2.该点在其中,计算point和item右边框的垂直距离
|
|
693
|
+
distance = Math.pow(
|
|
694
|
+
point.x - (x_pos + itemTemplateInfo.width - 1),
|
|
695
|
+
2
|
|
696
|
+
);
|
|
697
|
+
} else if (point.y > y_pos + itemTemplateInfo.height - 1) {
|
|
698
|
+
//3.该点在其下,计算point到item右下角的距离
|
|
699
|
+
distance =
|
|
700
|
+
Math.pow(point.x - (x_pos + itemTemplateInfo.width - 1), 2) +
|
|
701
|
+
Math.pow(point.y - (y_pos + itemTemplateInfo.height - 1), 2);
|
|
702
|
+
}
|
|
703
|
+
// point与item右边框的距离作为权值
|
|
704
|
+
direction_weighted = Math.abs(
|
|
705
|
+
point.x - (x_pos + itemTemplateInfo.width - 1)
|
|
706
|
+
);
|
|
707
|
+
break;
|
|
708
|
+
case "right":
|
|
709
|
+
if (point.x > x_pos) {
|
|
710
|
+
// 这个点在item右侧,不可能右移到item
|
|
711
|
+
continue;
|
|
712
|
+
}
|
|
713
|
+
if (point.y < y_pos) {
|
|
714
|
+
//1.该点在其上, 计算point和item左上角的距离
|
|
715
|
+
distance =
|
|
716
|
+
Math.pow(x_pos - point.x, 2) + Math.pow(y_pos - point.y, 2);
|
|
717
|
+
} else if (src_y_range.IsInterAct(target_y_range)) {
|
|
718
|
+
//2.该点在其中,计算point和item左边框的垂直距离
|
|
719
|
+
distance = Math.pow(x_pos - point.x, 2);
|
|
720
|
+
//(x2-x1)^2
|
|
721
|
+
} else if (point.y > y_pos + itemTemplateInfo.height - 1) {
|
|
722
|
+
//3.该点在其下,计算point和item左下角的距离
|
|
723
|
+
distance =
|
|
724
|
+
Math.pow(x_pos - point.x, 2) +
|
|
725
|
+
Math.pow(point.y - (y_pos + itemTemplateInfo.height - 1), 2);
|
|
726
|
+
}
|
|
727
|
+
// point与item左边框的距离作为权值
|
|
728
|
+
direction_weighted = Math.abs(point.x - x_pos);
|
|
729
|
+
break;
|
|
730
|
+
case "up":
|
|
731
|
+
if (point.y < y_pos + itemTemplateInfo.height - 1) {
|
|
732
|
+
// 这个点在item上侧,不可能上移到item
|
|
733
|
+
continue;
|
|
734
|
+
}
|
|
735
|
+
if (point.x < x_pos) {
|
|
736
|
+
//1.该点在其前,计算point和item右下角的距离
|
|
737
|
+
distance =
|
|
738
|
+
Math.pow(point.x - x_pos, 2) +
|
|
739
|
+
Math.pow(point.y - (y_pos + itemTemplateInfo.height - 1), 2);
|
|
740
|
+
} else if (src_x_range.IsInterAct(target_x_range)) {
|
|
741
|
+
//2.该点在其中,计算point和item下边框的垂直距离
|
|
742
|
+
distance = Math.pow(
|
|
743
|
+
point.y - (y_pos + itemTemplateInfo.height - 1),
|
|
744
|
+
2
|
|
745
|
+
);
|
|
746
|
+
} else if (point.x > x_pos + itemTemplateInfo.width - 1) {
|
|
747
|
+
//3.该点在其后,计算point和item左下角的距离
|
|
748
|
+
distance =
|
|
749
|
+
Math.pow(point.x - (x_pos + itemTemplateInfo.width - 1), 2) +
|
|
750
|
+
Math.pow(point.y - (y_pos + itemTemplateInfo.height - 1), 2);
|
|
751
|
+
}
|
|
752
|
+
// point与item下边框的距离作为权值
|
|
753
|
+
direction_weighted = Math.abs(
|
|
754
|
+
point.y - (y_pos + itemTemplateInfo.height - 1)
|
|
755
|
+
);
|
|
756
|
+
break;
|
|
757
|
+
case "down":
|
|
758
|
+
if (point.y > y_pos) {
|
|
759
|
+
// 这个点在item下侧,不可能下移到item
|
|
760
|
+
continue;
|
|
761
|
+
}
|
|
762
|
+
if (point.x < x_pos) {
|
|
763
|
+
//1.该点在其前,计算point和item右上角的距离
|
|
764
|
+
distance =
|
|
765
|
+
Math.pow(point.x - x_pos, 2) + Math.pow(y_pos - point.y, 2);
|
|
766
|
+
} else if (src_x_range.IsInterAct(target_x_range)) {
|
|
767
|
+
//2.该点在其中,计算point和item上边框的垂直距离
|
|
768
|
+
distance = Math.pow(y_pos - point.y, 2);
|
|
769
|
+
} else if (point.x > x_pos + itemTemplateInfo.width - 1) {
|
|
770
|
+
//3.该点在其后,计算point和item左上角的距离
|
|
771
|
+
distance =
|
|
772
|
+
Math.pow(point.x - (x_pos + itemTemplateInfo.width - 1), 2) +
|
|
773
|
+
Math.pow(y_pos - point.y, 2);
|
|
774
|
+
}
|
|
775
|
+
// point与item上边框的距离作为权值
|
|
776
|
+
direction_weighted = Math.abs(point.y - y_pos);
|
|
777
|
+
break;
|
|
778
|
+
default:
|
|
779
|
+
console.log("direction is error:" + direction);
|
|
780
|
+
break;
|
|
781
|
+
}
|
|
782
|
+
if (min_distance < 0) {
|
|
783
|
+
// 设置首个找到的项目
|
|
784
|
+
min_distance = distance;
|
|
785
|
+
min_direction_weighted = direction_weighted;
|
|
786
|
+
min_distance_item = itemTemplateInfo;
|
|
787
|
+
} else {
|
|
788
|
+
if (
|
|
789
|
+
min_direction_weighted > direction_weighted ||
|
|
790
|
+
(min_direction_weighted === direction_weighted &&
|
|
791
|
+
min_distance > distance)
|
|
792
|
+
) {
|
|
793
|
+
// 先进行权值比较,在权值相等时,再比较距离
|
|
794
|
+
min_distance = distance;
|
|
795
|
+
min_direction_weighted = direction_weighted;
|
|
796
|
+
min_distance_item = itemTemplateInfo;
|
|
797
|
+
}
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
|
|
802
|
+
if (min_distance_item) {
|
|
803
|
+
return min_distance_item.id;
|
|
804
|
+
} else {
|
|
805
|
+
return 0;
|
|
806
|
+
}
|
|
807
|
+
};
|
|
808
|
+
|
|
809
|
+
const focusBlockOnKeyDown = (ev) => {
|
|
810
|
+
if (onKeyDownLock) {
|
|
811
|
+
return true;
|
|
812
|
+
}
|
|
813
|
+
switch (ev.keyCode) {
|
|
814
|
+
case 37:
|
|
815
|
+
_moveToNext(-1, 0);
|
|
816
|
+
break;
|
|
817
|
+
case 38:
|
|
818
|
+
_moveToNext(0, -1);
|
|
819
|
+
break;
|
|
820
|
+
case 39:
|
|
821
|
+
_moveToNext(1, 0);
|
|
822
|
+
break;
|
|
823
|
+
case 40:
|
|
824
|
+
_moveToNext(0, 1);
|
|
825
|
+
break;
|
|
826
|
+
case 13:
|
|
827
|
+
onItemClick(getItemById(focusId));
|
|
828
|
+
break;
|
|
829
|
+
default:
|
|
830
|
+
//只接受上下左右确定键
|
|
831
|
+
return false;
|
|
832
|
+
}
|
|
833
|
+
return true;
|
|
834
|
+
};
|
|
835
|
+
|
|
836
|
+
const flushItemCoord = (index) => {
|
|
837
|
+
for (let i = index; i < innerData.length; ++i) {
|
|
838
|
+
const item = getItemByIndex(i);
|
|
839
|
+
const renderStyle = item.renderStyle;
|
|
840
|
+
const templateInfo = item.templateInfo;
|
|
841
|
+
renderStyle.left = templateInfo.left;
|
|
842
|
+
renderStyle.top = templateInfo.top;
|
|
843
|
+
renderStyle.width = templateInfo.width;
|
|
844
|
+
renderStyle.height = templateInfo.height;
|
|
845
|
+
}
|
|
846
|
+
};
|
|
847
|
+
|
|
848
|
+
const updateItemSize = (index, newSize, locateSet, animInfo = null) => {
|
|
849
|
+
if (index < 0 || !newSize) {
|
|
850
|
+
console.warn(TAG, "updateItemSize params invalid.");
|
|
851
|
+
return;
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
const keyItem = getItemByIndex(index);
|
|
855
|
+
if (
|
|
856
|
+
keyItem.renderStyle.width == newSize.width &&
|
|
857
|
+
keyItem.renderStyle.height == newSize.height
|
|
858
|
+
) {
|
|
859
|
+
return;
|
|
860
|
+
}
|
|
861
|
+
|
|
862
|
+
const keyItemPreRect = {
|
|
863
|
+
left: keyItem.templateInfo.left,
|
|
864
|
+
top: keyItem.templateInfo.top,
|
|
865
|
+
width: keyItem.templateInfo.width,
|
|
866
|
+
height: keyItem.templateInfo.height,
|
|
867
|
+
};
|
|
868
|
+
const preVisibleStart = visibleInfo.start;
|
|
869
|
+
|
|
870
|
+
metroTemplate.updateItemSize(index, newSize);
|
|
871
|
+
|
|
872
|
+
const locateType = locateSet?.type ?? METRO_WIDGET_CONST.ITEM_RESIZE.WIDGET_SET;
|
|
873
|
+
switch (locateType) {
|
|
874
|
+
case METRO_WIDGET_CONST.ITEM_RESIZE.ANCHOR:
|
|
875
|
+
let anchor = locateSet.anchor;
|
|
876
|
+
if (!checkType(anchor, Number)) {
|
|
877
|
+
console.error(`updateItemSize error: params of locateType 'ANCHOR' is invalid, expected Number but got ${typeof locateSet.anchor}.\n Use default anchor 0.`);
|
|
878
|
+
anchor = 0;
|
|
879
|
+
}
|
|
880
|
+
const sizeKey = vertical ? "height" : "width";
|
|
881
|
+
const newVisibleStart = Math.round(
|
|
882
|
+
keyItem.templateInfo[sizeKey] * anchor
|
|
883
|
+
+ preVisibleStart
|
|
884
|
+
- keyItemPreRect[sizeKey] * anchor
|
|
885
|
+
);
|
|
886
|
+
visibleInfo.start = newVisibleStart < 0 ? 0 : newVisibleStart;
|
|
887
|
+
break;
|
|
888
|
+
case METRO_WIDGET_CONST.ITEM_RESIZE.WIDGET_SET:
|
|
889
|
+
visibleInfo.start = _calculateVisibleStart(keyItem.templateInfo, preSeamlessSlideDirection);
|
|
890
|
+
break;
|
|
891
|
+
case METRO_WIDGET_CONST.ITEM_RESIZE.CUSTOMER_SET:
|
|
892
|
+
const customerFunc = locateSet.func;
|
|
893
|
+
if (!checkType(customerFunc, Function)) {
|
|
894
|
+
console.error(`updateItemSize error: params of locateType 'CUSTOMER_SETTING' is invalid, expected Function but got ${typeof locateSet.func}.\n Use locateType 'WIDGET_SETTING'`);
|
|
895
|
+
visibleInfo.start = _calculateVisibleStart(keyItem, preSeamlessSlideDirection);
|
|
896
|
+
break;
|
|
897
|
+
} else {
|
|
898
|
+
// 为了方便理解, 提供给外部以及外部返回的可视区域起始包含padding
|
|
899
|
+
const paddingStart = vertical ? widgetRectInfo.padding.top : widgetRectInfo.padding.left;
|
|
900
|
+
const newItemPadding = customerFunc(
|
|
901
|
+
keyItemPreRect,
|
|
902
|
+
{
|
|
903
|
+
left: keyItem.templateInfo.left,
|
|
904
|
+
top: keyItem.templateInfo.top,
|
|
905
|
+
width: keyItem.templateInfo.width,
|
|
906
|
+
height: keyItem.templateInfo.height,
|
|
907
|
+
},
|
|
908
|
+
(vertical ? keyItemPreRect.top : keyItemPreRect.left) - (preVisibleStart - paddingStart),
|
|
909
|
+
);
|
|
910
|
+
visibleInfo.start = (vertical ? keyItem.templateInfo.top : keyItem.templateInfo.left) - newItemPadding + paddingStart;
|
|
911
|
+
}
|
|
912
|
+
break;
|
|
913
|
+
default:
|
|
914
|
+
throw new Error("undefined locate type", locateSet.type);
|
|
915
|
+
}
|
|
916
|
+
|
|
917
|
+
const updater = pageUpdater.update(
|
|
918
|
+
metroTemplate,
|
|
919
|
+
visibleInfo.startWithPadding - props.keepTraceRange * pageRange,
|
|
920
|
+
Math.min(
|
|
921
|
+
visibleInfo.startMax + visibleInfo.range + visibleInfo.padding.end - 1,
|
|
922
|
+
visibleInfo.endWithPadding + props.keepTraceRange * pageRange
|
|
923
|
+
),
|
|
924
|
+
keyItem.id,
|
|
925
|
+
false,
|
|
926
|
+
permanentItemList
|
|
927
|
+
);
|
|
928
|
+
|
|
929
|
+
let renderList = [];
|
|
930
|
+
const tmpRange = pageUpdater.getTmpRange();
|
|
931
|
+
if (tmpRange) {
|
|
932
|
+
renderList = Array.from(tmpRange).map((i) => {
|
|
933
|
+
return getItemByIndex(i);
|
|
934
|
+
});
|
|
935
|
+
}
|
|
936
|
+
|
|
937
|
+
const preRectInfo = {};
|
|
938
|
+
for (let i of renderList) {
|
|
939
|
+
preRectInfo[i.index] = {
|
|
940
|
+
left: i.renderStyle.left,
|
|
941
|
+
top: i.renderStyle.top,
|
|
942
|
+
width: i.renderStyle.width,
|
|
943
|
+
height: i.renderStyle.height,
|
|
944
|
+
};
|
|
945
|
+
}
|
|
946
|
+
flushItemCoord(index);
|
|
947
|
+
|
|
948
|
+
//item animation
|
|
949
|
+
if (animInfo) {
|
|
950
|
+
const onItemMoveEnd = (animDone) => {
|
|
951
|
+
itemMovingInfo = null;
|
|
952
|
+
animInfo?.onEnd();
|
|
953
|
+
};
|
|
954
|
+
let curFrameCount = Forge.sFrameCount.count;
|
|
955
|
+
for (let i of renderList) {
|
|
956
|
+
if (i.index < index) {
|
|
957
|
+
continue;
|
|
958
|
+
}
|
|
959
|
+
if (
|
|
960
|
+
preRectInfo[i.index].left != i.renderStyle.left ||
|
|
961
|
+
preRectInfo[i.index].top != i.renderStyle.top
|
|
962
|
+
) {
|
|
963
|
+
itemMovingInfo = {
|
|
964
|
+
index: index,
|
|
965
|
+
deltaLeft: preRectInfo[i.index].left - i.renderStyle.left,
|
|
966
|
+
deltaTop: preRectInfo[i.index].top - i.renderStyle.top,
|
|
967
|
+
easing: animInfo.easing,
|
|
968
|
+
duration: animInfo.duration,
|
|
969
|
+
frameCount: curFrameCount,
|
|
970
|
+
};
|
|
971
|
+
}
|
|
972
|
+
const doItemAnim = (div) => {
|
|
973
|
+
const animNode = AnimationTools.getDivSlideAnim(
|
|
974
|
+
div,
|
|
975
|
+
preRectInfo[i.index].left - i.renderStyle.left,
|
|
976
|
+
preRectInfo[i.index].top - i.renderStyle.top,
|
|
977
|
+
0,
|
|
978
|
+
0,
|
|
979
|
+
{
|
|
980
|
+
easing: animInfo.easing ?? null,
|
|
981
|
+
duration: animInfo.duration ?? DEFAULT_ANIMATION_DURATION,
|
|
982
|
+
onEnd: i.index === index ? onItemMoveEnd : null,
|
|
983
|
+
}
|
|
984
|
+
);
|
|
985
|
+
animationManager.tryStartAnim(curFrameCount, animNode, i.index);
|
|
986
|
+
};
|
|
987
|
+
if (i.rootDiv) {
|
|
988
|
+
doItemAnim(toRaw(i.rootDiv));
|
|
989
|
+
} else {
|
|
990
|
+
i.addDivMountedListener(doItemAnim);
|
|
991
|
+
}
|
|
992
|
+
}
|
|
993
|
+
} else {
|
|
994
|
+
itemMovingInfo = null;
|
|
995
|
+
}
|
|
996
|
+
|
|
997
|
+
const slideDivPos =
|
|
998
|
+
(vertical ? itemResizeSlideTop.value : itemResizeSlideLeft.value) -
|
|
999
|
+
(visibleInfo.start - preVisibleStart);
|
|
1000
|
+
|
|
1001
|
+
if (animInfo) {
|
|
1002
|
+
const slideAnim = {
|
|
1003
|
+
easing: animInfo.easing ?? null,
|
|
1004
|
+
onStart: null,
|
|
1005
|
+
duration: animInfo.duration ?? DEFAULT_ANIMATION_DURATION,
|
|
1006
|
+
onEnd: (animDone) => {
|
|
1007
|
+
updater.apply();
|
|
1008
|
+
},
|
|
1009
|
+
};
|
|
1010
|
+
updater.applyTmp();
|
|
1011
|
+
|
|
1012
|
+
updateItemResizeSlideDiv(
|
|
1013
|
+
vertical ? 0 : slideDivPos,
|
|
1014
|
+
vertical ? slideDivPos : 0,
|
|
1015
|
+
slideAnim
|
|
1016
|
+
);
|
|
1017
|
+
} else {
|
|
1018
|
+
updateItemResizeSlideDiv(
|
|
1019
|
+
vertical ? 0 : slideDivPos,
|
|
1020
|
+
vertical ? slideDivPos : 0,
|
|
1021
|
+
null
|
|
1022
|
+
);
|
|
1023
|
+
pageUpdater.apply();
|
|
1024
|
+
}
|
|
1025
|
+
};
|
|
1026
|
+
|
|
1027
|
+
const _onTemplateAdd = (customerData, templateItem, measuresObj) => {
|
|
1028
|
+
let focusZIndex = -1,
|
|
1029
|
+
normalZIndex = -1;
|
|
1030
|
+
if (
|
|
1031
|
+
typeof measuresObj["zIndex"] != "undefined" &&
|
|
1032
|
+
measuresObj["zIndex"] != null
|
|
1033
|
+
) {
|
|
1034
|
+
if (typeof measuresObj["zIndex"] == "object") {
|
|
1035
|
+
if (typeof measuresObj["zIndex"]["focus"] == "number") {
|
|
1036
|
+
focusZIndex = measuresObj["zIndex"]["focus"];
|
|
1037
|
+
}
|
|
1038
|
+
if (typeof measuresObj["zIndex"]["normal"] == "number") {
|
|
1039
|
+
normalZIndex = measuresObj["zIndex"]["normal"];
|
|
1040
|
+
}
|
|
1041
|
+
} else if (typeof measuresObj["zIndex"] == "number") {
|
|
1042
|
+
focusZIndex = measuresObj["zIndex"];
|
|
1043
|
+
normalZIndex = measuresObj["zIndex"];
|
|
1044
|
+
}
|
|
1045
|
+
}
|
|
1046
|
+
let itemConfig = {
|
|
1047
|
+
focusZIndex,
|
|
1048
|
+
normalZIndex,
|
|
1049
|
+
permanent: measuresObj.permanent ?? false,
|
|
1050
|
+
doSlide: measuresObj.doSlide ?? true,
|
|
1051
|
+
takeOverSlide: false,
|
|
1052
|
+
};
|
|
1053
|
+
|
|
1054
|
+
if (props.itemConfig) {
|
|
1055
|
+
const c = props.itemConfig(customerData);
|
|
1056
|
+
itemConfig.takeOverSlide = c?.takeOverSlide ?? false;
|
|
1057
|
+
}
|
|
1058
|
+
|
|
1059
|
+
const renderStyle = reactive({
|
|
1060
|
+
left: templateItem.left,
|
|
1061
|
+
top: templateItem.top,
|
|
1062
|
+
width: templateItem.width,
|
|
1063
|
+
height: templateItem.height,
|
|
1064
|
+
zIndex: itemConfig.normalZIndex,
|
|
1065
|
+
});
|
|
1066
|
+
|
|
1067
|
+
const item = new RenderItem(
|
|
1068
|
+
templateItem,
|
|
1069
|
+
customerData,
|
|
1070
|
+
renderStyle,
|
|
1071
|
+
itemConfig,
|
|
1072
|
+
() => {
|
|
1073
|
+
if (callFocusAfterUpdate && item.id === focusId) {
|
|
1074
|
+
nextTick(() => {
|
|
1075
|
+
onItemFocus(item, preEdgeRect);
|
|
1076
|
+
});
|
|
1077
|
+
callFocusAfterUpdate = false;
|
|
1078
|
+
}
|
|
1079
|
+
},
|
|
1080
|
+
//query object
|
|
1081
|
+
{
|
|
1082
|
+
id: templateItem.id,
|
|
1083
|
+
index: templateItem.index,
|
|
1084
|
+
position: _getPosition,
|
|
1085
|
+
templatePosition: _getTemplatePosition,
|
|
1086
|
+
getCurrentFocusId: _getCurrentId,
|
|
1087
|
+
slideTo: slideTo,
|
|
1088
|
+
updateItemSize,
|
|
1089
|
+
widgetHandler: exportObject,
|
|
1090
|
+
}
|
|
1091
|
+
);
|
|
1092
|
+
|
|
1093
|
+
innerData.push(item);
|
|
1094
|
+
if (item.itemConfig.permanent) {
|
|
1095
|
+
permanentItemList.push({
|
|
1096
|
+
index: item.index - 1,
|
|
1097
|
+
alreadyShow: false,
|
|
1098
|
+
});
|
|
1099
|
+
}
|
|
1100
|
+
const lastTemplateInfo = getItemByIndex(metroTemplate.size - 1).templateInfo;
|
|
1101
|
+
if (vertical) {
|
|
1102
|
+
touchContainerH.value = lastTemplateInfo.top + lastTemplateInfo.height - 1;
|
|
1103
|
+
} else {
|
|
1104
|
+
touchContainerW.value = lastTemplateInfo.left + lastTemplateInfo.width - 1;
|
|
1105
|
+
}
|
|
1106
|
+
};
|
|
1107
|
+
|
|
1108
|
+
const _itemOnFocusSideEffect = (item, edgeRect) => {
|
|
1109
|
+
_onFocusChange(item.id);
|
|
1110
|
+
if (item.rootDiv) {
|
|
1111
|
+
let event = {
|
|
1112
|
+
type: "focusRect",
|
|
1113
|
+
direction: edgeRect?.direction?.description,
|
|
1114
|
+
element: toRaw(item.rootDiv),
|
|
1115
|
+
};
|
|
1116
|
+
_bubbleCustomerEvent(event);
|
|
1117
|
+
}
|
|
1118
|
+
};
|
|
1119
|
+
|
|
1120
|
+
const focusBlockOnCustomerEvent = (ev) => {
|
|
1121
|
+
if (ev.type === "focusRect") {
|
|
1122
|
+
if (childSlideEventLock) {
|
|
1123
|
+
return true;
|
|
1124
|
+
}
|
|
1125
|
+
if (ev.ownerNode == exportObject) {
|
|
1126
|
+
return false;
|
|
1127
|
+
}
|
|
1128
|
+
let item_div = ev.element;
|
|
1129
|
+
let direction = 0;
|
|
1130
|
+
if (props.direction == HORIZONTAL) {
|
|
1131
|
+
if (ev.direction == "left") {
|
|
1132
|
+
direction = -1;
|
|
1133
|
+
} else if (ev.direction == "right") {
|
|
1134
|
+
direction = 1;
|
|
1135
|
+
}
|
|
1136
|
+
} else {
|
|
1137
|
+
if (ev.direction == "top") {
|
|
1138
|
+
direction = -1;
|
|
1139
|
+
} else if (ev.direction == "bottom") {
|
|
1140
|
+
direction = 1;
|
|
1141
|
+
}
|
|
1142
|
+
}
|
|
1143
|
+
const item_layout = item_div.jsvGetRelativePosition(toRaw(locateDiv.value));
|
|
1144
|
+
|
|
1145
|
+
let fakeItem = {
|
|
1146
|
+
templateInfo: {
|
|
1147
|
+
left: item_layout.left,
|
|
1148
|
+
top: item_layout.top,
|
|
1149
|
+
width: item_layout.width,
|
|
1150
|
+
height: item_layout.height,
|
|
1151
|
+
centerYPos: Math.floor(item_layout.top + item_layout.height / 2),
|
|
1152
|
+
centerXPos: Math.floor(item_layout.left + item_layout.width / 2),
|
|
1153
|
+
index: id2Index(focusId),
|
|
1154
|
+
},
|
|
1155
|
+
};
|
|
1156
|
+
|
|
1157
|
+
let cur_slide = _calculateVisibleStart(fakeItem.templateInfo, direction);
|
|
1158
|
+
if (cur_slide != visibleInfo.start) {
|
|
1159
|
+
visibleInfo.start = cur_slide;
|
|
1160
|
+
const updater = pageUpdater.update(
|
|
1161
|
+
metroTemplate,
|
|
1162
|
+
visibleInfo.startWithPadding - props.keepTraceRange * pageRange,
|
|
1163
|
+
Math.min(
|
|
1164
|
+
visibleInfo.startMax +
|
|
1165
|
+
visibleInfo.range +
|
|
1166
|
+
visibleInfo.padding.end -
|
|
1167
|
+
1,
|
|
1168
|
+
visibleInfo.endWithPadding + props.keepTraceRange * pageRange
|
|
1169
|
+
),
|
|
1170
|
+
focusId,
|
|
1171
|
+
true,
|
|
1172
|
+
permanentItemList
|
|
1173
|
+
);
|
|
1174
|
+
updater.applyTmp();
|
|
1175
|
+
_slideTo(visibleInfo.start, {
|
|
1176
|
+
easing: "",
|
|
1177
|
+
onStart: null,
|
|
1178
|
+
speed: props.slideSetting.Speed,
|
|
1179
|
+
onEnd: () => {
|
|
1180
|
+
updater.apply();
|
|
1181
|
+
},
|
|
1182
|
+
});
|
|
1183
|
+
return true;
|
|
1184
|
+
}
|
|
1185
|
+
}
|
|
1186
|
+
return false;
|
|
1187
|
+
};
|
|
1188
|
+
|
|
1189
|
+
const _bubbleCustomerEvent = (event) => {
|
|
1190
|
+
if (props.sendFocusRectEvent && event) {
|
|
1191
|
+
event.ownerNode = exportObject;
|
|
1192
|
+
toRaw(focusNode.value)?.bubbleCustomerEvent(event);
|
|
1193
|
+
}
|
|
1194
|
+
};
|
|
1195
|
+
|
|
1196
|
+
const _moveToNext = (
|
|
1197
|
+
horizontal_direction,
|
|
1198
|
+
vertical_direction,
|
|
1199
|
+
item_edge_rect
|
|
1200
|
+
) => {
|
|
1201
|
+
//数据为空时
|
|
1202
|
+
if (innerData.length == 0) {
|
|
1203
|
+
let direction;
|
|
1204
|
+
if (horizontal_direction > 0) {
|
|
1205
|
+
direction = EdgeDirection.right;
|
|
1206
|
+
} else if (horizontal_direction < 0) {
|
|
1207
|
+
direction = EdgeDirection.left;
|
|
1208
|
+
} else if (vertical_direction > 0) {
|
|
1209
|
+
direction = EdgeDirection.bottom;
|
|
1210
|
+
} else if (vertical_direction < 0) {
|
|
1211
|
+
direction = EdgeDirection.top;
|
|
1212
|
+
} else {
|
|
1213
|
+
console.warn(TAG, "moveToNext error");
|
|
1214
|
+
}
|
|
1215
|
+
if (direction) {
|
|
1216
|
+
props.onEdge?.({
|
|
1217
|
+
direction: direction,
|
|
1218
|
+
rect: {
|
|
1219
|
+
x: 0,
|
|
1220
|
+
y: 0,
|
|
1221
|
+
width: 0,
|
|
1222
|
+
height: 0,
|
|
1223
|
+
},
|
|
1224
|
+
});
|
|
1225
|
+
}
|
|
1226
|
+
return;
|
|
1227
|
+
}
|
|
1228
|
+
let next_focus_item = getNextItem(
|
|
1229
|
+
focusId,
|
|
1230
|
+
vertical_direction,
|
|
1231
|
+
horizontal_direction,
|
|
1232
|
+
props.focusMoveType
|
|
1233
|
+
);
|
|
1234
|
+
if (next_focus_item !== null) {
|
|
1235
|
+
preFocusId = focusId;
|
|
1236
|
+
const preFocusItem = getItemByIndex(preFocusId);
|
|
1237
|
+
focusId = next_focus_item.id;
|
|
1238
|
+
|
|
1239
|
+
templateItemAdder.tryAddItem(next_focus_item.templateInfo, 1);
|
|
1240
|
+
|
|
1241
|
+
// itemFocus 和 itemBlur放在计算visibleStart之前, 以便用户更改template后在计算滚动
|
|
1242
|
+
let x_off_set = preFocusItem.templateInfo.left - next_focus_item.templateInfo.left;
|
|
1243
|
+
let y_off_set = preFocusItem.templateInfo.top - next_focus_item.templateInfo.top;
|
|
1244
|
+
if (item_edge_rect && item_edge_rect.rect) {
|
|
1245
|
+
item_edge_rect.rect.x += x_off_set;
|
|
1246
|
+
item_edge_rect.rect.y += y_off_set;
|
|
1247
|
+
preEdgeRect = item_edge_rect;
|
|
1248
|
+
} else {
|
|
1249
|
+
let direction;
|
|
1250
|
+
if (horizontal_direction > 0) {
|
|
1251
|
+
direction = EdgeDirection.right;
|
|
1252
|
+
} else if (horizontal_direction < 0) {
|
|
1253
|
+
direction = EdgeDirection.left;
|
|
1254
|
+
} else if (vertical_direction > 0) {
|
|
1255
|
+
direction = EdgeDirection.bottom;
|
|
1256
|
+
} else if (vertical_direction < 0) {
|
|
1257
|
+
direction = EdgeDirection.top;
|
|
1258
|
+
}
|
|
1259
|
+
preEdgeRect = {
|
|
1260
|
+
direction,
|
|
1261
|
+
rect: {
|
|
1262
|
+
x: x_off_set,
|
|
1263
|
+
y: y_off_set,
|
|
1264
|
+
width: preFocusItem.templateInfo.width,
|
|
1265
|
+
height: preFocusItem.templateInfo.height,
|
|
1266
|
+
},
|
|
1267
|
+
};
|
|
1268
|
+
}
|
|
1269
|
+
onItemBlur(preFocusItem);
|
|
1270
|
+
onItemFocus(next_focus_item, preEdgeRect);
|
|
1271
|
+
|
|
1272
|
+
let cur_visible_start = _calculateVisibleStart(next_focus_item.templateInfo, vertical ? vertical_direction : horizontal_direction);
|
|
1273
|
+
if (
|
|
1274
|
+
!next_focus_item.itemConfig.takeOverSlide &&
|
|
1275
|
+
visibleInfo.start !== cur_visible_start
|
|
1276
|
+
) {
|
|
1277
|
+
if (next_focus_item.itemConfig.doSlide) {
|
|
1278
|
+
visibleInfo.start = cur_visible_start;
|
|
1279
|
+
const updater = pageUpdater.update(
|
|
1280
|
+
metroTemplate,
|
|
1281
|
+
visibleInfo.startWithPadding - props.keepTraceRange * pageRange,
|
|
1282
|
+
Math.min(
|
|
1283
|
+
visibleInfo.startMax +
|
|
1284
|
+
visibleInfo.range +
|
|
1285
|
+
visibleInfo.padding.end -
|
|
1286
|
+
1,
|
|
1287
|
+
visibleInfo.endWithPadding + props.keepTraceRange * pageRange
|
|
1288
|
+
),
|
|
1289
|
+
next_focus_item.id,
|
|
1290
|
+
false,
|
|
1291
|
+
permanentItemList
|
|
1292
|
+
);
|
|
1293
|
+
updater.applyTmp();
|
|
1294
|
+
let animObj = {
|
|
1295
|
+
easing: "",
|
|
1296
|
+
onStart: null,
|
|
1297
|
+
speed: props.slideSetting.Speed,
|
|
1298
|
+
onEnd: (animDone) => {
|
|
1299
|
+
updater.apply();
|
|
1300
|
+
},
|
|
1301
|
+
};
|
|
1302
|
+
_slideTo(visibleInfo.start, animObj);
|
|
1303
|
+
} else {
|
|
1304
|
+
//不做滚动时,保证获焦的item创建
|
|
1305
|
+
const updater = pageUpdater.update(
|
|
1306
|
+
metroTemplate,
|
|
1307
|
+
cur_visible_start,
|
|
1308
|
+
cur_visible_start + visibleInfo.range + visibleInfo.padding.end - 1,
|
|
1309
|
+
next_focus_item.id,
|
|
1310
|
+
false,
|
|
1311
|
+
permanentItemList
|
|
1312
|
+
);
|
|
1313
|
+
updater.apply();
|
|
1314
|
+
}
|
|
1315
|
+
if (
|
|
1316
|
+
itemMovingInfo &&
|
|
1317
|
+
itemMovingInfo.frameCount == Forge.sFrameCount.count
|
|
1318
|
+
) {
|
|
1319
|
+
//缩放的动画正在进行时
|
|
1320
|
+
const tmpRangeList = pageUpdater.getTmpRange();
|
|
1321
|
+
for (let index of tmpRangeList) {
|
|
1322
|
+
const item = getItemByIndex(index);
|
|
1323
|
+
if (item.index > itemMovingInfo.index && !toRaw(item.rootDiv)) {
|
|
1324
|
+
item.addDivMountedListener((div) => {
|
|
1325
|
+
const animNode = AnimationTools.getDivSlideAnim(
|
|
1326
|
+
toRaw(div),
|
|
1327
|
+
itemMovingInfo.deltaLeft,
|
|
1328
|
+
itemMovingInfo.deltaTop,
|
|
1329
|
+
0,
|
|
1330
|
+
0,
|
|
1331
|
+
{
|
|
1332
|
+
easing: itemMovingInfo.easing,
|
|
1333
|
+
duration: itemMovingInfo.duration,
|
|
1334
|
+
}
|
|
1335
|
+
);
|
|
1336
|
+
animationManager.tryStartAnim(
|
|
1337
|
+
Forge.sFrameCount.count,
|
|
1338
|
+
animNode,
|
|
1339
|
+
item.index
|
|
1340
|
+
);
|
|
1341
|
+
});
|
|
1342
|
+
}
|
|
1343
|
+
}
|
|
1344
|
+
}
|
|
1345
|
+
}
|
|
1346
|
+
} else {
|
|
1347
|
+
//到达边缘
|
|
1348
|
+
let x_off_set = vertical ? 0 : visibleInfo.start;
|
|
1349
|
+
let y_off_set = vertical ? visibleInfo.start : 0;
|
|
1350
|
+
let edge;
|
|
1351
|
+
if (horizontal_direction === 1) {
|
|
1352
|
+
edge = EdgeDirection.right;
|
|
1353
|
+
}
|
|
1354
|
+
if (horizontal_direction === -1) {
|
|
1355
|
+
edge = EdgeDirection.left;
|
|
1356
|
+
}
|
|
1357
|
+
if (vertical_direction === 1) {
|
|
1358
|
+
edge = EdgeDirection.bottom;
|
|
1359
|
+
}
|
|
1360
|
+
if (vertical_direction === -1) {
|
|
1361
|
+
edge = EdgeDirection.top;
|
|
1362
|
+
}
|
|
1363
|
+
const curTemplateInfo = getItemById(focusId)?.templateInfo;
|
|
1364
|
+
let rect = {
|
|
1365
|
+
x: curTemplateInfo.left - x_off_set,
|
|
1366
|
+
y: curTemplateInfo.top - y_off_set,
|
|
1367
|
+
width: curTemplateInfo.width,
|
|
1368
|
+
height: curTemplateInfo.height,
|
|
1369
|
+
};
|
|
1370
|
+
props.onEdge?.({ direction: edge, rect: rect });
|
|
1371
|
+
innerData[id2Index(focusId)].onWidgetEdge({
|
|
1372
|
+
direction: edge,
|
|
1373
|
+
});
|
|
1374
|
+
}
|
|
1375
|
+
};
|
|
1376
|
+
|
|
1377
|
+
const _calculateVisibleStart = (targetTemplateInfo, direction) => {
|
|
1378
|
+
if (!targetTemplateInfo) {
|
|
1379
|
+
console.error("MetroWidget: _calculateVisibleStart target item is null");
|
|
1380
|
+
return 0;
|
|
1381
|
+
}
|
|
1382
|
+
|
|
1383
|
+
preSeamlessSlideDirection = direction;
|
|
1384
|
+
preAnchorItemIndex = targetTemplateInfo.index;
|
|
1385
|
+
let pos_key = vertical ? "top" : "left";
|
|
1386
|
+
let size_key = vertical ? "height" : "width";
|
|
1387
|
+
let center_key = vertical ? "centerYPos" : "centerXPos";
|
|
1388
|
+
let new_visible_start = visibleInfo.start;
|
|
1389
|
+
|
|
1390
|
+
switch (props.slideSetting.Type) {
|
|
1391
|
+
case SlideSetting.Type.FIX_POSITION:
|
|
1392
|
+
//FIX_POSITION 模式会将当前 item 的中心固定到指定位置
|
|
1393
|
+
new_visible_start = Math.ceil(
|
|
1394
|
+
targetTemplateInfo[center_key] -
|
|
1395
|
+
visibleInfo.range * props.slideSetting.FixPercent
|
|
1396
|
+
);
|
|
1397
|
+
break;
|
|
1398
|
+
case SlideSetting.Type.WHOLE_PAGE:
|
|
1399
|
+
if (typeof targetTemplateInfo.pageHeadIndex == "undefined") {
|
|
1400
|
+
//TODO 子控制滚动时whole page滚动
|
|
1401
|
+
console.error(
|
|
1402
|
+
"child controlled whole page slide type is not supported."
|
|
1403
|
+
);
|
|
1404
|
+
} else {
|
|
1405
|
+
new_visible_start = getItemByIndex(targetTemplateInfo.pageHeadIndex)
|
|
1406
|
+
.templateInfo[pos_key];
|
|
1407
|
+
}
|
|
1408
|
+
|
|
1409
|
+
break;
|
|
1410
|
+
case SlideSetting.Type.SEAMLESS:
|
|
1411
|
+
if (
|
|
1412
|
+
targetTemplateInfo[size_key] >=
|
|
1413
|
+
visibleInfo.range *
|
|
1414
|
+
(props.slideSetting.EndPercent - props.slideSetting.StartPercent)
|
|
1415
|
+
) {
|
|
1416
|
+
//尺寸较大的item
|
|
1417
|
+
new_visible_start =
|
|
1418
|
+
targetTemplateInfo[center_key] - visibleInfo.range * 0.5;
|
|
1419
|
+
} else {
|
|
1420
|
+
if (direction > 0) {
|
|
1421
|
+
if (
|
|
1422
|
+
targetTemplateInfo[pos_key] + targetTemplateInfo[size_key] >
|
|
1423
|
+
visibleInfo.start +
|
|
1424
|
+
visibleInfo.range * props.slideSetting.EndPercent
|
|
1425
|
+
) {
|
|
1426
|
+
new_visible_start =
|
|
1427
|
+
targetTemplateInfo[pos_key] +
|
|
1428
|
+
targetTemplateInfo[size_key] -
|
|
1429
|
+
visibleInfo.range * props.slideSetting.EndPercent;
|
|
1430
|
+
}
|
|
1431
|
+
} else if (direction < 0) {
|
|
1432
|
+
if (
|
|
1433
|
+
targetTemplateInfo[pos_key] <
|
|
1434
|
+
visibleInfo.start +
|
|
1435
|
+
visibleInfo.range * props.slideSetting.StartPercent
|
|
1436
|
+
) {
|
|
1437
|
+
new_visible_start =
|
|
1438
|
+
targetTemplateInfo[pos_key] -
|
|
1439
|
+
visibleInfo.range * props.slideSetting.StartPercent;
|
|
1440
|
+
}
|
|
1441
|
+
} else {
|
|
1442
|
+
//不是沿widget方向的移动
|
|
1443
|
+
if (targetTemplateInfo[pos_key] < visibleInfo.start) {
|
|
1444
|
+
new_visible_start =
|
|
1445
|
+
targetTemplateInfo[pos_key] -
|
|
1446
|
+
visibleInfo.range * props.slideSetting.StartPercent;
|
|
1447
|
+
} else if (
|
|
1448
|
+
targetTemplateInfo[pos_key] + targetTemplateInfo[size_key] >
|
|
1449
|
+
visibleInfo.end
|
|
1450
|
+
) {
|
|
1451
|
+
new_visible_start =
|
|
1452
|
+
targetTemplateInfo[pos_key] +
|
|
1453
|
+
targetTemplateInfo[size_key] -
|
|
1454
|
+
visibleInfo.range * props.slideSetting.EndPercent;
|
|
1455
|
+
}
|
|
1456
|
+
}
|
|
1457
|
+
}
|
|
1458
|
+
break;
|
|
1459
|
+
default:
|
|
1460
|
+
console.error(
|
|
1461
|
+
"MetroWidget: undefined slide type",
|
|
1462
|
+
props.slideSetting.Type
|
|
1463
|
+
);
|
|
1464
|
+
}
|
|
1465
|
+
|
|
1466
|
+
if ((props.slideSetting.BoundaryProtect & SlideSetting.START_PROTECT) > 0) {
|
|
1467
|
+
let boundary = 0;
|
|
1468
|
+
//首个元素是占位符时, 在保证获焦区域完全展示的前提下要保证首个不可获焦元素的完全展示
|
|
1469
|
+
const headTemplateInfo = getItemByIndex(0).templateInfo;
|
|
1470
|
+
if (
|
|
1471
|
+
!headTemplateInfo.focusable &&
|
|
1472
|
+
targetTemplateInfo[pos_key] + targetTemplateInfo[size_key] <=
|
|
1473
|
+
visibleInfo.range
|
|
1474
|
+
) {
|
|
1475
|
+
boundary = headTemplateInfo[size_key];
|
|
1476
|
+
}
|
|
1477
|
+
new_visible_start = new_visible_start < boundary ? 0 : new_visible_start;
|
|
1478
|
+
}
|
|
1479
|
+
if ((props.slideSetting.BoundaryProtect & SlideSetting.END_PROTECT) > 0) {
|
|
1480
|
+
let lastTemplateInfo = getItemByIndex(metroTemplate.size - 1).templateInfo;
|
|
1481
|
+
let last_visible_start =
|
|
1482
|
+
lastTemplateInfo[pos_key] +
|
|
1483
|
+
lastTemplateInfo[size_key] -
|
|
1484
|
+
visibleInfo.range;
|
|
1485
|
+
last_visible_start = last_visible_start < 0 ? 0 : last_visible_start;
|
|
1486
|
+
let boundary = last_visible_start;
|
|
1487
|
+
if (
|
|
1488
|
+
!lastTemplateInfo.focusable &&
|
|
1489
|
+
targetTemplateInfo[pos_key] - last_visible_start >= 0
|
|
1490
|
+
) {
|
|
1491
|
+
//最后元素是占位符, 在保证获焦区域完全展示的前提下要保证不可获焦元素的完全展示
|
|
1492
|
+
boundary = lastTemplateInfo[pos_key] - visibleInfo.range;
|
|
1493
|
+
}
|
|
1494
|
+
new_visible_start =
|
|
1495
|
+
new_visible_start > boundary ? last_visible_start : new_visible_start;
|
|
1496
|
+
}
|
|
1497
|
+
return Math.round(new_visible_start);
|
|
1498
|
+
};
|
|
1499
|
+
|
|
1500
|
+
const _onFocusableItemEdge = (edge_info) => {
|
|
1501
|
+
let horizontal_direction = 0;
|
|
1502
|
+
let vertical_direction = 0;
|
|
1503
|
+
switch (edge_info.direction) {
|
|
1504
|
+
case EdgeDirection.left:
|
|
1505
|
+
horizontal_direction = -1;
|
|
1506
|
+
break;
|
|
1507
|
+
case EdgeDirection.right:
|
|
1508
|
+
horizontal_direction = 1;
|
|
1509
|
+
break;
|
|
1510
|
+
case EdgeDirection.top:
|
|
1511
|
+
vertical_direction = -1;
|
|
1512
|
+
break;
|
|
1513
|
+
case EdgeDirection.bottom:
|
|
1514
|
+
vertical_direction = 1;
|
|
1515
|
+
break;
|
|
1516
|
+
default:
|
|
1517
|
+
break;
|
|
1518
|
+
}
|
|
1519
|
+
_moveToNext(horizontal_direction, vertical_direction, edge_info);
|
|
1520
|
+
};
|
|
1521
|
+
|
|
1522
|
+
const _ifValidEnterRect = (rect_info) => {
|
|
1523
|
+
return rect_info && rect_info.direction && rect_info.rect;
|
|
1524
|
+
};
|
|
1525
|
+
|
|
1526
|
+
const focusBlockOnFocus = (params) => {
|
|
1527
|
+
isFocus = true;
|
|
1528
|
+
preFocusId = -1;
|
|
1529
|
+
if (innerData.length === 0) {
|
|
1530
|
+
console.warn(`MetroWidget: ${props.name} get focus while data is empty.`);
|
|
1531
|
+
return;
|
|
1532
|
+
}
|
|
1533
|
+
let focus_id =
|
|
1534
|
+
typeof enterFocusId !== "undefined" &&
|
|
1535
|
+
enterFocusId >= 0 &&
|
|
1536
|
+
enterFocusId < metroTemplate.size
|
|
1537
|
+
? enterFocusId
|
|
1538
|
+
: focusId;
|
|
1539
|
+
focus_id = _ifValidEnterRect(enterFocusRect)
|
|
1540
|
+
? _calculateNearestItemByRect(pageUpdater.getRange(), enterFocusRect)
|
|
1541
|
+
: focus_id;
|
|
1542
|
+
|
|
1543
|
+
preEdgeRect = enterFocusRect;
|
|
1544
|
+
focusId = focus_id;
|
|
1545
|
+
enterFocusId = -1;
|
|
1546
|
+
enterFocusRect = null;
|
|
1547
|
+
onItemFocus(getItemById(focusId), preEdgeRect);
|
|
1548
|
+
props.onFocus?.();
|
|
1549
|
+
};
|
|
1550
|
+
|
|
1551
|
+
const focusBlockOnBlur = () => {
|
|
1552
|
+
enterFocusId = -1;
|
|
1553
|
+
enterFocusRect = null;
|
|
1554
|
+
preEdgeRect = null;
|
|
1555
|
+
preFocusId = focusId;
|
|
1556
|
+
console.log("testtest focusblock on blur", preFocusId)
|
|
1557
|
+
onItemBlur(getItemById(preFocusId));
|
|
1558
|
+
props.onBlur?.();
|
|
1559
|
+
isFocus = false;
|
|
1560
|
+
};
|
|
1561
|
+
|
|
1562
|
+
const _updateFocusByDragInfo = (viewX, viewY) => {
|
|
1563
|
+
let enterFocusRect = null;
|
|
1564
|
+
//模拟最小区域作为输入区域
|
|
1565
|
+
if (vertical) {
|
|
1566
|
+
enterFocusRect = {
|
|
1567
|
+
direction: EdgeDirection.top,
|
|
1568
|
+
rect: {
|
|
1569
|
+
x: props.left - viewX,
|
|
1570
|
+
y: props.top - viewY,
|
|
1571
|
+
width: 10,
|
|
1572
|
+
height: 10,
|
|
1573
|
+
},
|
|
1574
|
+
};
|
|
1575
|
+
} else {
|
|
1576
|
+
enterFocusRect = {
|
|
1577
|
+
direction: EdgeDirection.left,
|
|
1578
|
+
rect: {
|
|
1579
|
+
x: props.left - viewX,
|
|
1580
|
+
y: props.top - viewY,
|
|
1581
|
+
width: 10,
|
|
1582
|
+
height: 10,
|
|
1583
|
+
},
|
|
1584
|
+
};
|
|
1585
|
+
}
|
|
1586
|
+
focusId = _calculateNearestItemByRect(pageUpdater.getRange(), enterFocusRect);
|
|
1587
|
+
};
|
|
1588
|
+
|
|
1589
|
+
const _onDragUpdateItem = (visible_start, visible_end) => {
|
|
1590
|
+
templateItemAdder.tryAddItemByPosition(visible_end);
|
|
1591
|
+
const updater = pageUpdater.update(
|
|
1592
|
+
metroTemplate,
|
|
1593
|
+
visible_start,
|
|
1594
|
+
visible_end,
|
|
1595
|
+
0,
|
|
1596
|
+
false,
|
|
1597
|
+
permanentItemList
|
|
1598
|
+
);
|
|
1599
|
+
updater.apply();
|
|
1600
|
+
|
|
1601
|
+
Forge.sRenderBridge.InstantPerformSwap();
|
|
1602
|
+
};
|
|
1603
|
+
|
|
1604
|
+
const _getTouchListener = () => {
|
|
1605
|
+
if (!props.enableTouch) {
|
|
1606
|
+
return null;
|
|
1607
|
+
}
|
|
1608
|
+
let callback = {
|
|
1609
|
+
OnDragStart: (msg) => {
|
|
1610
|
+
if (mounted) {
|
|
1611
|
+
Promise.resolve().then(() => {
|
|
1612
|
+
let cur_visible_start = visibleInfo.start - pageRange * 2;
|
|
1613
|
+
let cur_visible_end = visibleInfo.start + pageRange * 3 - 1;
|
|
1614
|
+
preUpdateVisibleStart = cur_visible_start;
|
|
1615
|
+
_onDragUpdateItem(cur_visible_start, cur_visible_end);
|
|
1616
|
+
});
|
|
1617
|
+
}
|
|
1618
|
+
return true;
|
|
1619
|
+
},
|
|
1620
|
+
OnMoved: (msg) => {
|
|
1621
|
+
if (mounted) {
|
|
1622
|
+
Promise.resolve().then(() => {
|
|
1623
|
+
if (
|
|
1624
|
+
typeof msg.viewY != "undefined" &&
|
|
1625
|
+
typeof msg.viewX != "undefined"
|
|
1626
|
+
) {
|
|
1627
|
+
if (vertical) {
|
|
1628
|
+
visibleInfo.start = -msg.viewY;
|
|
1629
|
+
} else {
|
|
1630
|
+
visibleInfo.start = -msg.viewX;
|
|
1631
|
+
}
|
|
1632
|
+
if (visibleInfo.start < 0) {
|
|
1633
|
+
visibleInfo.start = 0;
|
|
1634
|
+
}
|
|
1635
|
+
}
|
|
1636
|
+
if (
|
|
1637
|
+
Math.abs(visibleInfo.start - preUpdateVisibleStart) <= pageRange
|
|
1638
|
+
) {
|
|
1639
|
+
let cur_visible_start = visibleInfo.start - pageRange * 2;
|
|
1640
|
+
let cur_visible_end = visibleInfo.start + pageRange * 3 - 1;
|
|
1641
|
+
preUpdateVisibleStart = cur_visible_start;
|
|
1642
|
+
_onDragUpdateItem(cur_visible_start, cur_visible_end);
|
|
1643
|
+
}
|
|
1644
|
+
});
|
|
1645
|
+
}
|
|
1646
|
+
|
|
1647
|
+
return true;
|
|
1648
|
+
},
|
|
1649
|
+
OnDragEnd: (msg) => {
|
|
1650
|
+
updateSlideDiv(msg["viewX"], msg["viewY"], null);
|
|
1651
|
+
preUpdateVisibleStart = visibleInfo.start;
|
|
1652
|
+
_onDragUpdateItem(
|
|
1653
|
+
visibleInfo.startWithPadding,
|
|
1654
|
+
visibleInfo.endWithPadding
|
|
1655
|
+
);
|
|
1656
|
+
_updateFocusByDragInfo(msg["viewX"], msg["viewY"]);
|
|
1657
|
+
_onScroll();
|
|
1658
|
+
return true;
|
|
1659
|
+
},
|
|
1660
|
+
OnFling: (msg) => {
|
|
1661
|
+
updateSlideDiv(msg["viewX"], msg["viewY"], null);
|
|
1662
|
+
preUpdateVisibleStart = visibleInfo.start;
|
|
1663
|
+
_onDragUpdateItem(
|
|
1664
|
+
visibleInfo.startWithPadding,
|
|
1665
|
+
visibleInfo.endWithPadding
|
|
1666
|
+
);
|
|
1667
|
+
_updateFocusByDragInfo(msg["viewX"], msg["viewY"]);
|
|
1668
|
+
_onScroll();
|
|
1669
|
+
return true;
|
|
1670
|
+
},
|
|
1671
|
+
OnRelease: (msg) => {
|
|
1672
|
+
return true;
|
|
1673
|
+
},
|
|
1674
|
+
};
|
|
1675
|
+
return callback;
|
|
1676
|
+
};
|
|
1677
|
+
|
|
1678
|
+
const _updatePage = (rangeSet) => {
|
|
1679
|
+
const tmpArray = Array.from(rangeSet);
|
|
1680
|
+
renderData.value = tmpArray.map((item) => {
|
|
1681
|
+
return getItemByIndex(item);
|
|
1682
|
+
});
|
|
1683
|
+
if (props.enableItemRenderBreak) {
|
|
1684
|
+
itemRender.value = false;
|
|
1685
|
+
nextTick(() => {
|
|
1686
|
+
itemRender.value = true;
|
|
1687
|
+
});
|
|
1688
|
+
}
|
|
1689
|
+
};
|
|
1690
|
+
|
|
1691
|
+
const _onScroll = () => {
|
|
1692
|
+
if (props.onScroll) {
|
|
1693
|
+
const lastTemplateInfo = getItemByIndex(
|
|
1694
|
+
metroTemplate.size - 1
|
|
1695
|
+
).templateInfo;
|
|
1696
|
+
let totalWidth;
|
|
1697
|
+
if (vertical) {
|
|
1698
|
+
totalWidth = lastTemplateInfo.top + lastTemplateInfo.height - 1;
|
|
1699
|
+
} else {
|
|
1700
|
+
totalWidth = lastTemplateInfo.left + lastTemplateInfo.width - 1;
|
|
1701
|
+
}
|
|
1702
|
+
props.onScroll(visibleInfo.start, visibleInfo.range, totalWidth);
|
|
1703
|
+
}
|
|
1704
|
+
};
|
|
1705
|
+
|
|
1706
|
+
const _initRootTouch = () => {
|
|
1707
|
+
if (props.enableTouch && toRaw(slideDiv.value)) {
|
|
1708
|
+
let view = toRaw(slideDiv.value).jsvGetProxyView(true);
|
|
1709
|
+
var drag_setting = new Forge.DragSetting(
|
|
1710
|
+
dragDirection,
|
|
1711
|
+
20,
|
|
1712
|
+
false,
|
|
1713
|
+
slidePile,
|
|
1714
|
+
props.flingPageWidth,
|
|
1715
|
+
props.flingPageEdge
|
|
1716
|
+
);
|
|
1717
|
+
view.EnableDrag(drag_setting, touchListener, "translateMat(dx,dy,0)");
|
|
1718
|
+
}
|
|
1719
|
+
};
|
|
1720
|
+
|
|
1721
|
+
const _initItemViewTouch = (itemDivRef, index) => {
|
|
1722
|
+
if (props.enableTouch) {
|
|
1723
|
+
if (itemDivRef) {
|
|
1724
|
+
// 为view添加触控处理
|
|
1725
|
+
let view = itemDivRef.jsvGetProxyView(true);
|
|
1726
|
+
let dragSetting = new Forge.DragSetting(
|
|
1727
|
+
Forge.DragSetting.DIRECTION_DISABLE,
|
|
1728
|
+
20,
|
|
1729
|
+
false,
|
|
1730
|
+
new Forge.RectArea(0, 0, 0, 0),
|
|
1731
|
+
-1,
|
|
1732
|
+
3 / 4
|
|
1733
|
+
);
|
|
1734
|
+
let callback = {
|
|
1735
|
+
OnTap: (msg) => {
|
|
1736
|
+
return onItemClick(getItemById(index));
|
|
1737
|
+
},
|
|
1738
|
+
};
|
|
1739
|
+
view.EnableDrag(dragSetting, callback, "translateMat(dx,dy,0)");
|
|
1740
|
+
}
|
|
1741
|
+
}
|
|
1742
|
+
};
|
|
1743
|
+
|
|
1744
|
+
//init
|
|
1745
|
+
pageUpdater = new PageUpdater(_updatePage);
|
|
1746
|
+
dragDirection = vertical
|
|
1747
|
+
? Forge.DragSetting.DIRECTION_VERTICAL
|
|
1748
|
+
: Forge.DragSetting.DIRECTION_HORIZONTAL;
|
|
1749
|
+
visibleInfo.range = vertical
|
|
1750
|
+
? widgetRectInfo.contentHeight
|
|
1751
|
+
: widgetRectInfo.contentWidth;
|
|
1752
|
+
visibleInfo.padding = vertical
|
|
1753
|
+
? { start: widgetRectInfo.padding.top, end: widgetRectInfo.padding.bottom }
|
|
1754
|
+
: { start: widgetRectInfo.padding.left, end: widgetRectInfo.padding.right };
|
|
1755
|
+
|
|
1756
|
+
if (props.provideData) {
|
|
1757
|
+
dataList = toRaw(props.provideData());
|
|
1758
|
+
} else if (props.data) {
|
|
1759
|
+
dataList = toRaw(props.data);
|
|
1760
|
+
}
|
|
1761
|
+
|
|
1762
|
+
window.metroTemplate = metroTemplate;
|
|
1763
|
+
window.innerData = innerData;
|
|
1764
|
+
|
|
1765
|
+
templateItemAdder = new TemplateItemAdder(
|
|
1766
|
+
metroTemplate,
|
|
1767
|
+
dataList,
|
|
1768
|
+
props.measures,
|
|
1769
|
+
pageRange,
|
|
1770
|
+
_onTemplateAdd,
|
|
1771
|
+
props.name
|
|
1772
|
+
);
|
|
1773
|
+
if (props.onScroll) {
|
|
1774
|
+
templateItemAdder.tryAddItemByIndex(dataList.length - 1);
|
|
1775
|
+
} else {
|
|
1776
|
+
templateItemAdder.tryAddItem(null, 2);
|
|
1777
|
+
}
|
|
1778
|
+
|
|
1779
|
+
//触控相关
|
|
1780
|
+
const lastTemplateInfo = getItemByIndex(metroTemplate.size - 1)?.templateInfo;
|
|
1781
|
+
if (lastTemplateInfo) {
|
|
1782
|
+
touchListener = _getTouchListener();
|
|
1783
|
+
touchContainerW.value =
|
|
1784
|
+
vertical
|
|
1785
|
+
? props.width
|
|
1786
|
+
: lastTemplateInfo.left + lastTemplateInfo.width;
|
|
1787
|
+
touchContainerH.value =
|
|
1788
|
+
vertical
|
|
1789
|
+
? lastTemplateInfo.top + lastTemplateInfo.height
|
|
1790
|
+
: props.height;
|
|
1791
|
+
}
|
|
1792
|
+
slidePile = new Forge.RectArea(
|
|
1793
|
+
0,
|
|
1794
|
+
0,
|
|
1795
|
+
widgetRectInfo.contentWidth,
|
|
1796
|
+
widgetRectInfo.contentHeight,
|
|
1797
|
+
);
|
|
1798
|
+
let init_focus_id = 0;
|
|
1799
|
+
let cur_visible_start = 0;
|
|
1800
|
+
|
|
1801
|
+
if (typeof props.initFocusId == "number") {
|
|
1802
|
+
templateItemAdder.tryAddItemById(props.initFocusId);
|
|
1803
|
+
const item = getItemById(props.initFocusId);
|
|
1804
|
+
if (item) {
|
|
1805
|
+
init_focus_id = props.initFocusId;
|
|
1806
|
+
if (item.itemConfig.doSlide) {
|
|
1807
|
+
cur_visible_start = _calculateVisibleStart(item.templateInfo, 1);
|
|
1808
|
+
}
|
|
1809
|
+
}
|
|
1810
|
+
}
|
|
1811
|
+
focusId = init_focus_id;
|
|
1812
|
+
visibleInfo.start = cur_visible_start;
|
|
1813
|
+
|
|
1814
|
+
const updater = pageUpdater.update(
|
|
1815
|
+
metroTemplate,
|
|
1816
|
+
visibleInfo.startWithPadding,
|
|
1817
|
+
visibleInfo.endWithPadding,
|
|
1818
|
+
0,
|
|
1819
|
+
false,
|
|
1820
|
+
permanentItemList
|
|
1821
|
+
);
|
|
1822
|
+
updater.apply();
|
|
1823
|
+
|
|
1824
|
+
onMounted(() => {
|
|
1825
|
+
mounted = true;
|
|
1826
|
+
_initRootTouch();
|
|
1827
|
+
for (let item of renderData.value) {
|
|
1828
|
+
_initItemViewTouch(toRaw(item.rootDiv), item.index);
|
|
1829
|
+
}
|
|
1830
|
+
|
|
1831
|
+
if (visibleInfo.start) {
|
|
1832
|
+
_slideTo(visibleInfo.start, null);
|
|
1833
|
+
}
|
|
1834
|
+
|
|
1835
|
+
onItemFocus(getItemById(focusId), preEdgeRect);
|
|
1836
|
+
|
|
1837
|
+
if (props.enableItemRenderBreak) {
|
|
1838
|
+
nextTick(() => {
|
|
1839
|
+
itemRender.value = true;
|
|
1840
|
+
});
|
|
1841
|
+
}
|
|
1842
|
+
});
|
|
1843
|
+
|
|
1844
|
+
onUpdated(() => {
|
|
1845
|
+
for (let item of renderData.value) {
|
|
1846
|
+
if (!item.touchInit) {
|
|
1847
|
+
_initItemViewTouch(toRaw(item.rootDiv), item.index);
|
|
1848
|
+
}
|
|
1849
|
+
}
|
|
1850
|
+
});
|
|
1851
|
+
|
|
1852
|
+
onBeforeUnmount(() => {
|
|
1853
|
+
mounted = false;
|
|
1854
|
+
});
|
|
1855
|
+
|
|
1856
|
+
return {
|
|
1857
|
+
widgetRectInfo,
|
|
1858
|
+
focusBlockOnFocus,
|
|
1859
|
+
focusBlockOnBlur,
|
|
1860
|
+
focusBlockOnKeyDown,
|
|
1861
|
+
focusBlockOnCustomerEvent,
|
|
1862
|
+
_onFocusableItemEdge,
|
|
1863
|
+
exportObject,
|
|
1864
|
+
}
|
|
1865
|
+
}
|
|
1866
|
+
|
|
1867
|
+
export const RENDER_ITEM_BREAK_KEY = "__QcodeJsviewMetroWidgetSlot";
|