@shijiu/jsview-vue 2.3.0 → 2.3.151-test.0

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.
Files changed (56) hide show
  1. package/bin/browser/BrowserAudio.vue.mjs +4 -1
  2. package/bin/jsview-vue.mjs +2200 -466
  3. package/bin/types/utils/JsViewEngineWidget/JsvFocus/JsvFocusHub.d.ts +21 -1
  4. package/bin/types/utils/JsViewEngineWidget/MetroWidget/RenderItem.d.ts +5 -1
  5. package/bin/types/utils/JsViewEngineWidget/TemplateParser/CommonMetroTemplate.d.ts +2 -1
  6. package/bin/types/utils/JsViewEngineWidget/WidgetCommon.d.ts +10 -7
  7. package/bin/types/utils/JsViewVueTools/ForgeHandles.d.ts +1 -0
  8. package/bin/types/utils/JsViewVueTools/JsvRuntimeBridge.d.ts +37 -1
  9. package/bin/types/utils/JsViewVueTools/JsvTextureStore/CapturedTexture/CapturedTexture.d.ts +3 -3
  10. package/bin/types/utils/JsViewVueTools/JsvTextureStore/DominantColor/GetDominantColor.d.ts +7 -0
  11. package/bin/types/utils/JsViewVueTools/JsvTextureStore/JsvTextureStore.d.ts +14 -1
  12. package/bin/types/utils/JsViewVueTools/JsvTextureStore/Store.d.ts +2 -0
  13. package/bin/types/utils/JsViewVueTools/JsvTextureStore/Texture.d.ts +4 -0
  14. package/bin/types/utils/JsViewVueWidget/JsvDashPath.vue.d.ts +11 -0
  15. package/bin/types/utils/JsViewVueWidget/JsvFragShaderView/JsvFragShaderView.vue.d.ts +2 -1
  16. package/bin/types/utils/JsViewVueWidget/JsvSmoothSlideContainer.vue.d.ts +72 -0
  17. package/bin/types/utils/JsViewVueWidget/JsvSoundPool.d.ts +26 -0
  18. package/bin/types/utils/JsViewVueWidget/JsvSwiper/JsvSmoothSwiper.vue.d.ts +112 -0
  19. package/bin/types/utils/JsViewVueWidget/JsvSwiper/JsvSwiper2.vue.d.ts +142 -0
  20. package/bin/types/utils/JsViewVueWidget/JsvSwiper/index.d.ts +3 -1
  21. package/bin/types/utils/JsViewVueWidget/JsvTextureAnim/JsvTextureAnim.vue.d.ts +2 -2
  22. package/bin/types/utils/JsViewVueWidget/index.d.ts +2 -1
  23. package/package.json +1 -1
  24. package/utils/JsViewEngineWidget/JsvFocus/JsvFocusHub.ts +27 -1
  25. package/utils/JsViewEngineWidget/MetroWidget/MetroWidget.vue +35 -3
  26. package/utils/JsViewEngineWidget/MetroWidget/MetroWidgetSetup.js +736 -386
  27. package/utils/JsViewEngineWidget/MetroWidget/RenderItem.ts +13 -2
  28. package/utils/JsViewEngineWidget/MetroWidget/TaskManager.ts +38 -26
  29. package/utils/JsViewEngineWidget/TemplateParser/CommonMetroTemplate.ts +144 -73
  30. package/utils/JsViewEngineWidget/WidgetCommon.ts +12 -0
  31. package/utils/JsViewPlugin/JsvAudio/BrowserAudio/BrowserAudio.vue +4 -0
  32. package/utils/JsViewPlugin/JsvAudio/BrowserAudio/JsvSystemAudio.vue +13 -13
  33. package/utils/JsViewPlugin/JsvPlayer/BrowserJsvPlayer.vue +1 -1
  34. package/utils/JsViewVueTools/FeatureActive.ts +2 -1
  35. package/utils/JsViewVueTools/ForgeHandles.ts +5 -2
  36. package/utils/JsViewVueTools/JsvRuntimeBridge.js +97 -1
  37. package/utils/JsViewVueTools/JsvTextTools.ts +3 -1
  38. package/utils/JsViewVueTools/JsvTextureStore/CapturedTexture/CapturedTexture.ts +15 -12
  39. package/utils/JsViewVueTools/JsvTextureStore/DominantColor/GetDominantColor.ts +36 -0
  40. package/utils/JsViewVueTools/JsvTextureStore/JsvTextureStore.ts +23 -2
  41. package/utils/JsViewVueTools/JsvTextureStore/Store.ts +33 -21
  42. package/utils/JsViewVueTools/JsvTextureStore/Texture.ts +56 -41
  43. package/utils/JsViewVueWidget/JsvDashPath.vue +150 -0
  44. package/utils/JsViewVueWidget/JsvFlexCell/JsvFullScrAdjust.vue +3 -1
  45. package/utils/JsViewVueWidget/JsvFragShaderView/JsvFragShaderView.vue +26 -22
  46. package/utils/JsViewVueWidget/JsvFreeMoveActor/SetAction.ts +1 -1
  47. package/utils/JsViewVueWidget/JsvInput/JsvInput.vue +1 -0
  48. package/utils/JsViewVueWidget/JsvPreload/JsvPreload.vue +2 -2
  49. package/utils/JsViewVueWidget/JsvSmoothSlideContainer.vue +108 -0
  50. package/utils/JsViewVueWidget/JsvSoundPool.js +75 -12
  51. package/utils/JsViewVueWidget/JsvSwiper/JsvSmoothSwiper.vue +543 -0
  52. package/utils/JsViewVueWidget/JsvSwiper/JsvSwiper.vue +3 -3
  53. package/utils/JsViewVueWidget/JsvSwiper/JsvSwiper2.vue +644 -0
  54. package/utils/JsViewVueWidget/JsvSwiper/index.js +3 -1
  55. package/utils/JsViewVueWidget/JsvTextureAnim/JsvTextureAnim.vue +14 -8
  56. package/utils/JsViewVueWidget/index.js +2 -1
@@ -27,9 +27,17 @@ import { RenderItem } from "./RenderItem";
27
27
  import { VisibleInfo } from "./VisibleInfo";
28
28
  import { WidgetRectInfo } from "./WidgetRectInfo";
29
29
  import ActorControl from "../../JsViewVueWidget/JsvFreeMoveActor/ActorControl.ts";
30
- import { TaskType, TaskManager, AnimationManager, SlideTaskType } from "./TaskManager.ts";
30
+ import {
31
+ TaskType,
32
+ TaskManager,
33
+ AnimationManager,
34
+ SlideTaskType,
35
+ } from "./TaskManager.ts";
31
36
  import { getDirectionByRect, RectCache } from "./Slide.ts";
32
- import { FeatureNames, JsvUseFeature } from "../../JsViewVueTools/FeatureActive.ts";
37
+ import {
38
+ FeatureNames,
39
+ JsvUseFeature,
40
+ } from "../../JsViewVueTools/FeatureActive.ts";
33
41
  import { randomColor } from "./DebugTools.ts";
34
42
 
35
43
  const TAG = "MetroWidget";
@@ -93,13 +101,17 @@ export const setup = (
93
101
  pageUpdateToken,
94
102
  touchDiv,
95
103
  touchDivSize,
96
- templateMode) => {
97
-
104
+ templateMode
105
+ ) => {
98
106
  if (props.itemConfig) {
99
- console.error(TAG, "prop: itemCofig will be deprecated soon.")
107
+ console.error(TAG, "prop: itemCofig will be deprecated soon.");
100
108
  }
101
109
 
102
- let widgetRectInfo = new WidgetRectInfo(props.width, props.height, props.padding);
110
+ let widgetRectInfo = new WidgetRectInfo(
111
+ props.width,
112
+ props.height,
113
+ props.padding
114
+ );
103
115
  let metroTemplate = _getMetroTemplate(
104
116
  widgetRectInfo,
105
117
  props.direction,
@@ -121,7 +133,7 @@ export const setup = (
121
133
  } else {
122
134
  if (props.touchFlag > 0) {
123
135
  // 激活引擎功能的支持
124
- JsvUseFeature('MetroWidget', FeatureNames.TouchReceiver);
136
+ JsvUseFeature("MetroWidget", FeatureNames.TouchReceiver);
125
137
 
126
138
  //触控默认3屏
127
139
  innerKeepTraceRange = 3;
@@ -165,8 +177,7 @@ export const setup = (
165
177
  this._touchState = TouchState.DRAG;
166
178
  }
167
179
  },
168
- dragEnd(touchCount) {
169
- },
180
+ dragEnd(touchCount) {},
170
181
  keyDown() {
171
182
  this._mode = FOCUS_MODE;
172
183
  modeForExport.value = FOCUS_MODE;
@@ -186,8 +197,8 @@ export const setup = (
186
197
  },
187
198
  getTouchCount() {
188
199
  return this._touchCount;
189
- }
190
- }
200
+ },
201
+ };
191
202
 
192
203
  let innerData = [];
193
204
  let dataList = [];
@@ -209,7 +220,7 @@ export const setup = (
209
220
  let onKeyDownLock = false;
210
221
  let visibleInfo = new VisibleInfo();
211
222
  let firstOnItemFocusCalled = false;
212
- let innerSlideSetting = props.slideSetting
223
+ let innerSlideSetting = props.slideSetting;
213
224
  const currentFocusIndex = ref(0);
214
225
 
215
226
  // 当sliderDiv变化时,渲染端在响应此变化前的gap记录,用于准确计算getVisibleStart
@@ -225,25 +236,33 @@ export const setup = (
225
236
  }
226
237
  let pos_key = vertical ? "top" : "left";
227
238
  let size_key = vertical ? "height" : "width";
228
- if (rect[pos_key] + rect[size_key] - 1 < visibleInfo.start || rect[pos_key] > visibleInfo.end) {
239
+ if (
240
+ rect[pos_key] + rect[size_key] - 1 < visibleInfo.start ||
241
+ rect[pos_key] > visibleInfo.end
242
+ ) {
229
243
  return 0; // 完全不可见
230
- } else if (rect[pos_key] < visibleInfo.start || rect[pos_key] + rect[size_key] - 1 > visibleInfo.end) {
244
+ } else if (
245
+ rect[pos_key] < visibleInfo.start ||
246
+ rect[pos_key] + rect[size_key] - 1 > visibleInfo.end
247
+ ) {
231
248
  return 1; // 部分可见
232
249
  } else {
233
250
  return 2; // 完全可见
234
251
  }
235
- }
252
+ };
236
253
 
237
254
  //tools
238
255
  const lastOfArray = (array) => {
239
256
  if (array instanceof Array && array.length > 0) {
240
- return array[array.length - 1]
257
+ return array[array.length - 1];
241
258
  }
242
259
  return null;
243
- }
260
+ };
244
261
 
245
262
  const onAddTask = (allTask) => {
246
- if (!innerData || innerData.length <= 0) { return; }
263
+ if (!innerData || innerData.length <= 0) {
264
+ return;
265
+ }
247
266
  let resizeTaskMap = {};
248
267
  //统一处理itemResize和slide动画
249
268
  let minIndex = Infinity;
@@ -264,24 +283,25 @@ export const setup = (
264
283
  doAnim: false,
265
284
  duration: 200,
266
285
  easing: "",
267
- }
286
+ };
268
287
  let resizeList = allTask.resize.concat();
269
288
  if (resizeList.length > 0) {
270
289
  //resize
271
- resizeList.forEach(task => {
290
+ resizeList.forEach((task) => {
272
291
  resizeTaskMap[task.params.index] = task;
273
292
  const { index, animInfo } = task.params;
274
293
  if (animInfo) {
275
294
  resizeAnimInfo.doAnim = true;
276
- resizeAnimInfo.duration = animInfo.duration ?? resizeAnimInfo.duration;
277
- resizeAnimInfo.easing = animInfo.duration ?? "";
295
+ resizeAnimInfo.duration =
296
+ animInfo.duration ?? resizeAnimInfo.duration;
297
+ resizeAnimInfo.easing = animInfo.easing ?? "";
278
298
  }
279
299
  minIndex = Math.min(minIndex, index);
280
300
 
281
301
  metroTemplate.updateItemSize(task.params.index, {
282
302
  width: task.params.width,
283
303
  height: task.params.height,
284
- })
304
+ });
285
305
  });
286
306
 
287
307
  //更新touch的size
@@ -292,12 +312,17 @@ export const setup = (
292
312
  const task = resizeTaskMap[id2Index(focusId)];
293
313
  const animInfo = task.params.animInfo;
294
314
  if (typeof animInfo?.anchor == "number") {
295
- const preRect = getItemById(focusId)?.templateInfo?.layoutCache.getPreRect();
315
+ const preRect =
316
+ getItemById(focusId)?.templateInfo?.layoutCache.getPreRect();
296
317
  if (preRect) {
297
318
  anchorInfo = {
298
- anchorPosition: preRect[pos_key] + preRect[size_key] * animInfo.anchor - 1 - visibleInfo.start,
319
+ anchorPosition:
320
+ preRect[pos_key] +
321
+ preRect[size_key] * animInfo.anchor -
322
+ 1 -
323
+ visibleInfo.start,
299
324
  anchor: animInfo.anchor,
300
- }
325
+ };
301
326
  }
302
327
  }
303
328
  }
@@ -322,48 +347,64 @@ export const setup = (
322
347
  slideDoAnim = slideTask.params.doAnim;
323
348
  forceSlide = slideTask.params.force;
324
349
  switch (slideTask.subType) {
325
- case SlideTaskType.SLIDE_BY_DIV: {
326
- const div = slideTask.params.div;
327
- const item_layout = div.jsvGetRelativePosition(toRaw(locateDiv.value));
328
- let fakeItem = {
329
- templateInfo: {
330
- left: item_layout.left,
331
- top: item_layout.top,
332
- width: item_layout.width,
333
- height: item_layout.height,
334
- centerYPos: Math.floor(item_layout.top + item_layout.height / 2),
335
- centerXPos: Math.floor(item_layout.left + item_layout.width / 2),
336
- index: id2Index(focusId),
337
- },
338
- };
339
- templateItemAdder.tryAddItemByPosition(vertical ? fakeItem.templateInfo.top : fakeItem.templateInfo.left);
340
- targetRect = fakeItem.templateInfo;
341
- } break;
342
- case SlideTaskType.SLIDE_BY_POS: {
343
- const position = slideTask.params.position;
344
- templateItemAdder.tryAddItemByPosition(position);
345
- targetVisibleStart = position;
346
- } break;
347
- case SlideTaskType.SLIDE_BY_ITEM: {
348
- const index = slideTask.params.index;
349
- templateItemAdder.tryAddItemByIndex(index);
350
- const targetItem = getItemByIndex(index);
351
- if (targetItem) {
350
+ case SlideTaskType.SLIDE_BY_DIV:
351
+ {
352
+ const div = slideTask.params.div;
353
+ const item_layout = div.jsvGetRelativePosition(
354
+ toRaw(locateDiv.value)
355
+ );
356
+ let fakeItem = {
357
+ templateInfo: {
358
+ left: item_layout.left,
359
+ top: item_layout.top,
360
+ width: item_layout.width,
361
+ height: item_layout.height,
362
+ centerYPos: Math.floor(
363
+ item_layout.top + item_layout.height / 2
364
+ ),
365
+ centerXPos: Math.floor(
366
+ item_layout.left + item_layout.width / 2
367
+ ),
368
+ index: id2Index(focusId),
369
+ },
370
+ };
371
+ templateItemAdder.tryAddItemByPosition(
372
+ vertical ? fakeItem.templateInfo.top : fakeItem.templateInfo.left
373
+ );
374
+ targetRect = fakeItem.templateInfo;
375
+ }
376
+ break;
377
+ case SlideTaskType.SLIDE_BY_POS:
378
+ {
379
+ const position = slideTask.params.position;
380
+ templateItemAdder.tryAddItemByPosition(position);
381
+ targetVisibleStart = position;
382
+ }
383
+ break;
384
+ case SlideTaskType.SLIDE_BY_ITEM:
385
+ {
386
+ const index = slideTask.params.index;
387
+ templateItemAdder.tryAddItemByIndex(index);
388
+ const targetItem = getItemByIndex(index);
389
+ if (targetItem) {
390
+ if (typeof slideTask.params.direction != "undefined") {
391
+ direction = slideTask.params.direction;
392
+ }
393
+ targetRect = targetItem.templateInfo;
394
+ } else {
395
+ //无效的滚动
396
+ validSlideTask = false;
397
+ }
398
+ }
399
+ break;
400
+ case SlideTaskType.SLIDE_BY_RECT:
401
+ {
352
402
  if (typeof slideTask.params.direction != "undefined") {
353
403
  direction = slideTask.params.direction;
354
404
  }
355
- targetRect = targetItem.templateInfo;
356
- } else {
357
- //无效的滚动
358
- validSlideTask = false;
359
- }
360
- } break;
361
- case SlideTaskType.SLIDE_BY_RECT: {
362
- if (typeof slideTask.params.direction != "undefined") {
363
- direction = slideTask.params.direction;
405
+ targetRect = slideTask.params.rect;
364
406
  }
365
- targetRect = slideTask.params.rect;
366
- } break;
407
+ break;
367
408
  default:
368
409
  break;
369
410
  }
@@ -375,20 +416,39 @@ export const setup = (
375
416
  if (anchorInfo) {
376
417
  //保持anchor
377
418
  const focusItem = getItemById(focusId);
378
- let start = focusItem.templateInfo[pos_key] + focusItem.templateInfo[size_key] * anchorInfo.anchor - 1 - anchorInfo.anchorPosition;
419
+ let start =
420
+ focusItem.templateInfo[pos_key] +
421
+ focusItem.templateInfo[size_key] * anchorInfo.anchor -
422
+ 1 -
423
+ anchorInfo.anchorPosition;
379
424
  let totalSize = metroTemplate.getBoundingBoxSize();
380
- start = Math.min(Math.max(0, start), totalSize[size_key] - visibleInfo.range)
425
+ start = Math.min(
426
+ Math.max(0, start),
427
+ totalSize[size_key] - visibleInfo.range
428
+ );
381
429
  //resize的情况下, 需要保证第一个和最后一个尺寸变化后, 能完整展示
382
430
  if (focusItem.index == 0) {
383
431
  if (start > focusItem.templateInfo[pos_key]) {
384
432
  start = 0;
385
433
  }
386
- } else if (focusItem.templateInfo.index == metroTemplate.getTailItemIndex()) {
434
+ } else if (
435
+ focusItem.templateInfo.index == metroTemplate.getTailItemIndex()
436
+ ) {
387
437
  if (start + visibleInfo.range > focusItem.templateInfo[pos_key]) {
388
- start = Math.max(focusItem.templateInfo[size_key] + focusItem.templateInfo[pos_key] - visibleInfo.range, 0);
438
+ start = Math.max(
439
+ focusItem.templateInfo[size_key] +
440
+ focusItem.templateInfo[pos_key] -
441
+ visibleInfo.range,
442
+ 0
443
+ );
389
444
  }
390
445
  }
391
- targetVisibleStart = normalizeVisibleStart(start, focusItem.templateInfo, focusItem.templateInfo.index, visibleInfo);
446
+ targetVisibleStart = normalizeVisibleStart(
447
+ start,
448
+ focusItem.templateInfo,
449
+ focusItem.templateInfo.index,
450
+ visibleInfo
451
+ );
392
452
  } else {
393
453
  targetRect = getItemById(focusId).templateInfo;
394
454
  }
@@ -403,11 +463,20 @@ export const setup = (
403
463
  preInfo = mRectCache.getPreRect();
404
464
  if (preInfo) {
405
465
  let totalSize = metroTemplate.getBoundingBoxSize();
406
- v.start = Math.min(Math.max(0, targetRect[pos_key] - preInfo[pos_key] + v.start), Math.max(0, totalSize[size_key] - v.range));
407
- preInfo[pos_key] += (v.start - visibleInfo.start);
466
+ v.start = Math.min(
467
+ Math.max(0, targetRect[pos_key] - preInfo[pos_key] + v.start),
468
+ Math.max(0, totalSize[size_key] - v.range)
469
+ );
470
+ preInfo[pos_key] += v.start - visibleInfo.start;
408
471
  }
409
472
  }
410
- targetVisibleStart = _calculateVisibleStart(targetRect, direction, targetRect, v, preInfo);
473
+ targetVisibleStart = _calculateVisibleStart(
474
+ targetRect,
475
+ direction,
476
+ targetRect,
477
+ v,
478
+ preInfo
479
+ );
411
480
  } else {
412
481
  //resize通过anchor直接设置了visibleStart
413
482
  if (resizeList.length > 0) {
@@ -419,7 +488,7 @@ export const setup = (
419
488
  width: tRect.width,
420
489
  height: tRect.height,
421
490
  frameCount: Forge.sFrameCount.count,
422
- })
491
+ });
423
492
  }
424
493
  }
425
494
  }
@@ -432,12 +501,12 @@ export const setup = (
432
501
  visibleInfo.start = targetVisibleStart;
433
502
  return () => {
434
503
  visibleInfo.start = preVisibleStart;
435
- }
504
+ };
436
505
  });
437
506
  }
438
507
 
439
508
  //updatePage
440
- let updateHandler
509
+ let updateHandler;
441
510
  taskManager.run(() => {
442
511
  updateHandler = pageUpdater.update(
443
512
  metroTemplate,
@@ -449,8 +518,8 @@ export const setup = (
449
518
  );
450
519
  return () => {
451
520
  updateHandler.recover();
452
- }
453
- })
521
+ };
522
+ });
454
523
 
455
524
  // resize item 动画
456
525
  if (resizeList.length > 0) {
@@ -462,7 +531,8 @@ export const setup = (
462
531
  const renderItem = getItemByIndex(index);
463
532
  const { left, top } = renderItem.templateInfo;
464
533
  if (index >= minIndex) {
465
- const layoutCache = renderItem.templateInfo.layoutCache.getPreRect();
534
+ const layoutCache =
535
+ renderItem.templateInfo.layoutCache.getPreRect();
466
536
  if (layoutCache) {
467
537
  const doItemSlide = (div) => {
468
538
  taskManager.run(() => {
@@ -470,15 +540,18 @@ export const setup = (
470
540
  div,
471
541
  [layoutCache.left - left, layoutCache.top - top],
472
542
  [0, 0],
473
- resizeTaskMap[index] ?
474
- resizeTaskMap[index].params.animInfo
475
- : { duration: resizeAnimInfo.duration }
476
- )
543
+ resizeTaskMap[index]
544
+ ? resizeTaskMap[index].params.animInfo
545
+ : {
546
+ duration: resizeAnimInfo.duration,
547
+ easing: resizeAnimInfo.easing,
548
+ }
549
+ );
477
550
  return () => {
478
- cancel()
479
- }
551
+ cancel();
552
+ };
480
553
  });
481
- }
554
+ };
482
555
 
483
556
  if (renderItem.mounted.value) {
484
557
  doItemSlide(renderItem.rootDiv);
@@ -501,14 +574,18 @@ export const setup = (
501
574
  let animInfo = undefined;
502
575
  if (slideDoAnim) {
503
576
  animInfo = {
504
- easing: null,//resizeAnimInfo.doAnim ? resizeAnimInfo.easing : '' /* innerSlideSetting.Easing */,
505
- duration: resizeAnimInfo.doAnim ? resizeAnimInfo.duration : innerSlideSetting.Duration,
577
+ easing: resizeAnimInfo.doAnim
578
+ ? resizeAnimInfo.easing
579
+ : innerSlideSetting.Easing /* innerSlideSetting.Easing */,
580
+ duration: resizeAnimInfo.doAnim
581
+ ? resizeAnimInfo.duration
582
+ : innerSlideSetting.Duration,
506
583
  speed: innerSlideSetting.Speed,
507
584
  onStart: null,
508
585
  onEnd: null,
509
- }
586
+ };
510
587
  }
511
- executeSlide(visibleInfo.start, animInfo, updateHandler)
588
+ executeSlide(visibleInfo.start, animInfo, updateHandler);
512
589
  }
513
590
 
514
591
  //回调
@@ -519,8 +596,8 @@ export const setup = (
519
596
  }, 0);
520
597
  return () => {
521
598
  clearTimeout(handler);
522
- }
523
- })
599
+ };
600
+ });
524
601
  }
525
602
  if ((needSlide || allTask.focus.length > 0) && props.onFocusRectChange) {
526
603
  taskManager.run(() => {
@@ -529,10 +606,10 @@ export const setup = (
529
606
  }, 0);
530
607
  return () => {
531
608
  clearTimeout(handler);
532
- }
533
- })
609
+ };
610
+ });
534
611
  }
535
- }
612
+ };
536
613
  const taskManager = new TaskManager(onAddTask);
537
614
  const animationManager = new AnimationManager();
538
615
 
@@ -545,12 +622,14 @@ export const setup = (
545
622
  return () => {
546
623
  slideDivLeft.value = preLeft;
547
624
  slideDivTop.value = preTop;
548
- }
625
+ };
549
626
  });
550
627
  if (animObj) {
551
628
  updateHandler.applyTmp();
552
629
  taskManager.run(() => {
553
- const from = vertical ? [0, preTop - slideDivTop.value] : [preLeft - slideDivLeft.value, 0];
630
+ const from = vertical
631
+ ? [0, preTop - slideDivTop.value]
632
+ : [preLeft - slideDivLeft.value, 0];
554
633
  const cancel = animationManager.startSlideAnim(
555
634
  slideDiv.value,
556
635
  from,
@@ -558,13 +637,13 @@ export const setup = (
558
637
  {
559
638
  ...animObj,
560
639
  onEnd: () => {
561
- updateHandler.apply()
562
- }
640
+ updateHandler.apply();
641
+ },
563
642
  }
564
643
  );
565
644
  return () => {
566
- cancel()
567
- }
645
+ cancel();
646
+ };
568
647
  });
569
648
  } else {
570
649
  updateHandler.apply();
@@ -575,28 +654,31 @@ export const setup = (
575
654
  }, 0);
576
655
  return () => {
577
656
  clearTimeout(handler);
578
- }
579
- })
580
- }
657
+ };
658
+ });
659
+ };
581
660
 
582
661
  const updateItemSize = (index, newSize, animInfo) => {
583
662
  const item = getItemByIndex(index);
584
- if (item && (item.templateInfo.width !== newSize.width || item.templateInfo.height !== newSize.height)) {
585
- taskManager.addTask(TaskType.RESIZE_ITEM,
586
- {
587
- index,
588
- width: newSize.width,
589
- height: newSize.height,
590
- animInfo,
591
- preRect: {
592
- left: item.templateInfo.left,
593
- top: item.templateInfo.top,
594
- width: item.templateInfo.width,
595
- height: item.templateInfo.height,
596
- },
597
- });
663
+ if (
664
+ item &&
665
+ (item.templateInfo.width !== newSize.width ||
666
+ item.templateInfo.height !== newSize.height)
667
+ ) {
668
+ taskManager.addTask(TaskType.RESIZE_ITEM, {
669
+ index,
670
+ width: newSize.width,
671
+ height: newSize.height,
672
+ animInfo,
673
+ preRect: {
674
+ left: item.templateInfo.left,
675
+ top: item.templateInfo.top,
676
+ width: item.templateInfo.width,
677
+ height: item.templateInfo.height,
678
+ },
679
+ });
598
680
  }
599
- }
681
+ };
600
682
 
601
683
  let callFocusAfterUpdate = false;
602
684
 
@@ -682,7 +764,9 @@ export const setup = (
682
764
  };
683
765
 
684
766
  const onItemClick = (item) => {
685
- if (!item) { return };
767
+ if (!item) {
768
+ return;
769
+ }
686
770
  if (isFocus) {
687
771
  item.onClick();
688
772
  }
@@ -696,7 +780,7 @@ export const setup = (
696
780
  }
697
781
  };
698
782
 
699
- let gazeIndex = -1
783
+ let gazeIndex = -1;
700
784
  const onItemFocus = (focusItem, rect) => {
701
785
  //触控模式不触发item的onFocus
702
786
  if (!focusItem) return;
@@ -711,7 +795,7 @@ export const setup = (
711
795
  if (preGazeItem) {
712
796
  preGazeItem.onIgnore();
713
797
  }
714
- gazeIndex = focusItem.templateInfo.index
798
+ gazeIndex = focusItem.templateInfo.index;
715
799
  focusItem.onGaze(rect);
716
800
  }
717
801
  if (isFocus) {
@@ -725,14 +809,35 @@ export const setup = (
725
809
  };
726
810
 
727
811
  const onItemLongPress = (item) => {
728
- if (!item) { return; }
812
+ if (!item) {
813
+ return;
814
+ }
729
815
  if (isFocus) {
730
816
  item.onLongPress();
731
817
  }
732
- }
818
+ };
733
819
 
734
- const setFocusByUid = (uid, needSlide = true, doAnim = false, extraSetting) => {
735
- if (!uid || innerData.length <= 0) { return; }
820
+ //tap的时候触发ongaze
821
+ const onItemTap = (gazeItem) => {
822
+ if (gazeIndex != gazeItem.templateInfo.index) {
823
+ let preGazeItem = getItemByIndex(gazeIndex);
824
+ if (preGazeItem) {
825
+ preGazeItem.onIgnore();
826
+ }
827
+ gazeIndex = gazeItem.templateInfo.index;
828
+ gazeItem.onGaze(null);
829
+ }
830
+ };
831
+
832
+ const setFocusByUid = (
833
+ uid,
834
+ needSlide = true,
835
+ doAnim = false,
836
+ extraSetting
837
+ ) => {
838
+ if (!uid || innerData.length <= 0) {
839
+ return;
840
+ }
736
841
  //添加item
737
842
  templateItemAdder.tryAddItemByUid(uid);
738
843
  const item = metroTemplate.getItemByUid(uid);
@@ -742,7 +847,7 @@ export const setup = (
742
847
  }
743
848
 
744
849
  setFocusId(item.id, needSlide, doAnim, extraSetting);
745
- }
850
+ };
746
851
 
747
852
  const setFocusId = (id, needSlide = true, doAnim = false, extraSetting) => {
748
853
  if (id == focusId || innerData.length <= 0) {
@@ -840,20 +945,32 @@ export const setup = (
840
945
  const setZIndex = (index, normalZIndex, focusZIndex) => {
841
946
  const targetItem = getItemByIndex(index);
842
947
  if (targetItem) {
843
- const n = normalZIndex, f = focusZIndex ?? normalZIndex;
948
+ const n = normalZIndex,
949
+ f = focusZIndex ?? normalZIndex;
844
950
 
845
951
  targetItem.itemConfig.focusZIndex = f;
846
952
  targetItem.itemConfig.normalZIndex = n;
847
953
  const focused = isFocus && focusId == index2Id(index);
848
954
  setItemZIndex(targetItem, focused ? f : n, focused);
849
955
  }
850
- }
956
+ };
851
957
 
852
- const slideToInner = (position, doAnim, updateParam = { mergeTmp: false }) => {
853
- if (slideLock || position == (vertical ? slideDivTop.value : slideDivLeft.value)) {
854
- return
855
- };
856
- taskManager.addTask(TaskType.SLIDE, { position, doAnim, updateParam }, SlideTaskType.SLIDE_BY_POS);
958
+ const slideToInner = (
959
+ position,
960
+ doAnim,
961
+ updateParam = { mergeTmp: false }
962
+ ) => {
963
+ if (
964
+ slideLock ||
965
+ position == (vertical ? slideDivTop.value : slideDivLeft.value)
966
+ ) {
967
+ return;
968
+ }
969
+ taskManager.addTask(
970
+ TaskType.SLIDE,
971
+ { position, doAnim, updateParam },
972
+ SlideTaskType.SLIDE_BY_POS
973
+ );
857
974
  };
858
975
 
859
976
  const slideTo = (position, doAnim) => {
@@ -862,7 +979,13 @@ export const setup = (
862
979
  }
863
980
  };
864
981
 
865
- const slideToItemInner = (index, doAnim, direction = undefined, preItem = undefined, force = false) => {
982
+ const slideToItemInner = (
983
+ index,
984
+ doAnim,
985
+ direction = undefined,
986
+ preItem = undefined,
987
+ force = false
988
+ ) => {
866
989
  taskManager.addTask(
867
990
  TaskType.SLIDE,
868
991
  {
@@ -872,15 +995,16 @@ export const setup = (
872
995
  preItem,
873
996
  force,
874
997
  },
875
- SlideTaskType.SLIDE_BY_ITEM);
998
+ SlideTaskType.SLIDE_BY_ITEM
999
+ );
876
1000
  };
877
1001
  const slideToItem = (index, doAnim) => {
878
- slideToItemInner(index, doAnim)
879
- }
1002
+ slideToItemInner(index, doAnim);
1003
+ };
880
1004
 
881
1005
  const slideToDiv = (div, doAnim) => {
882
1006
  slideToDivInner(div, doAnim);
883
- }
1007
+ };
884
1008
  const slideToDivInner = (div, doAnim, direction = undefined) => {
885
1009
  if (div) {
886
1010
  taskManager.addTask(
@@ -890,37 +1014,46 @@ export const setup = (
890
1014
  doAnim,
891
1015
  direction,
892
1016
  },
893
- SlideTaskType.SLIDE_BY_DIV);
1017
+ SlideTaskType.SLIDE_BY_DIV
1018
+ );
894
1019
  }
895
- }
1020
+ };
896
1021
  const slideToRectInner = (rect, doAnim, direction, force) => {
897
- if (rect && typeof rect.left == "number" && typeof rect.top == "number" && typeof rect.width == "number" && typeof rect.height == "number") {
1022
+ if (
1023
+ rect &&
1024
+ typeof rect.left == "number" &&
1025
+ typeof rect.top == "number" &&
1026
+ typeof rect.width == "number" &&
1027
+ typeof rect.height == "number"
1028
+ ) {
898
1029
  taskManager.addTask(
899
1030
  TaskType.SLIDE,
900
1031
  {
901
1032
  rect,
902
1033
  doAnim,
903
1034
  direction,
904
- force
1035
+ force,
905
1036
  },
906
1037
  SlideTaskType.SLIDE_BY_RECT
907
1038
  );
908
1039
  }
909
- }
1040
+ };
910
1041
  const slideToRect = (rect, doAnim, direction = undefined) => {
911
1042
  slideToRectInner(rect, doAnim, direction, false);
912
- }
1043
+ };
913
1044
 
914
1045
  function ifLayoutChange(type, oldMeasureItem, newMeasureItem) {
915
- let changed = newMeasureItem.width !== oldMeasureItem.width
916
- || newMeasureItem.height !== oldMeasureItem.height
917
- || newMeasureItem.focusable !== oldMeasureItem.focusable
918
- || newMeasureItem.marginRight !== oldMeasureItem.marginRight
919
- || newMeasureItem.marginBottom !== oldMeasureItem.marginBottom;
1046
+ let changed =
1047
+ newMeasureItem.width !== oldMeasureItem.width ||
1048
+ newMeasureItem.height !== oldMeasureItem.height ||
1049
+ newMeasureItem.focusable !== oldMeasureItem.focusable ||
1050
+ newMeasureItem.marginRight !== oldMeasureItem.marginRight ||
1051
+ newMeasureItem.marginBottom !== oldMeasureItem.marginBottom;
920
1052
  if (type !== "relative") {
921
- changed = changed
922
- || newMeasureItem.left !== oldMeasureItem.left
923
- || newMeasureItem.top !== oldMeasureItem.top
1053
+ changed =
1054
+ changed ||
1055
+ newMeasureItem.left !== oldMeasureItem.left ||
1056
+ newMeasureItem.top !== oldMeasureItem.top;
924
1057
  }
925
1058
  return changed;
926
1059
  }
@@ -942,68 +1075,78 @@ export const setup = (
942
1075
  let maxSameIndex = -1;
943
1076
  let layoutChange = false;
944
1077
  let onlyDataChangeList = [];
945
- let targetFocusId = focusId
946
- if (focusId >= newData.length) {
947
- targetFocusId = newData.length - 1
948
- }
949
-
950
- if (!forceUpdate) {
951
- for (let i = 0; i < dataList.length; ++i) {
952
- let oldItem = dataList[i];
953
- let newItem = newData[i];
954
- if (newItem) {
955
- if (((typeof newItem[DATA_ID_KEY] == "undefined" || typeof dataKeyList[i] == "undefined") && newItem === oldItem)
956
- || (typeof newItem[DATA_ID_KEY] !== "undefined" && typeof dataKeyList[i] !== "undefined" && newItem[DATA_ID_KEY] === dataKeyList[i])) {
957
- //相同的item
958
- maxSameIndex = Math.max(maxSameIndex, i);
959
- } else {
960
- const newMeasureItem = props.measures(newItem);
961
- const oldMeasureItem = props.measures(oldItem);
962
- layoutChange = ifLayoutChange(props.layoutType, oldMeasureItem, newMeasureItem);
963
- if (layoutChange) {
964
- break;
1078
+ let targetFocusId = focusId;
1079
+ let curFocusItemChanged = true;
1080
+ if (newData.length == 0) {
1081
+ layoutChange = true;
1082
+ targetFocusId = -1;
1083
+ } else {
1084
+ if (focusId < 0) {
1085
+ targetFocusId = 0;
1086
+ } else if (focusId >= newData.length) {
1087
+ targetFocusId = newData.length - 1;
1088
+ }
1089
+ if (!forceUpdate) {
1090
+ const curFocusIndex = id2Index(focusId);
1091
+ for (let i = 0; i < dataList.length; ++i) {
1092
+ let oldItem = dataList[i];
1093
+ let newItem = newData[i];
1094
+ if (newItem) {
1095
+ if (
1096
+ ((typeof newItem[DATA_ID_KEY] == "undefined" ||
1097
+ typeof dataKeyList[i] == "undefined") &&
1098
+ newItem === oldItem) ||
1099
+ (typeof newItem[DATA_ID_KEY] !== "undefined" &&
1100
+ typeof dataKeyList[i] !== "undefined" &&
1101
+ newItem[DATA_ID_KEY] === dataKeyList[i])
1102
+ ) {
1103
+ //相同的item
1104
+ maxSameIndex = Math.max(maxSameIndex, i);
1105
+ if (curFocusIndex == i) {
1106
+ curFocusItemChanged = false;
1107
+ }
965
1108
  } else {
966
- if (i < innerData.length) {
967
- onlyDataChangeList.push({
968
- templateInfo: innerData[i].templateInfo,
969
- measureObj: newMeasureItem,
970
- data: newItem,
971
- index: i,
972
- });
1109
+ const newMeasureItem = props.measures(newItem);
1110
+ const oldMeasureItem = props.measures(oldItem);
1111
+ layoutChange = ifLayoutChange(
1112
+ props.layoutType,
1113
+ oldMeasureItem,
1114
+ newMeasureItem
1115
+ );
1116
+ if (layoutChange) {
1117
+ break;
1118
+ } else {
1119
+ if (i < innerData.length) {
1120
+ onlyDataChangeList.push({
1121
+ templateInfo: innerData[i].templateInfo,
1122
+ measureObj: newMeasureItem,
1123
+ data: newItem,
1124
+ index: i,
1125
+ });
1126
+ }
973
1127
  }
974
1128
  }
975
- }
976
- } else {
977
- if (i >= newData.length) {
978
- //item减少需要布局改变
979
- layoutChange = true;
980
- break;
981
1129
  } else {
982
- //数据中存在undefined item
983
- throw new Error("undefined item in data list.", i, newData);
1130
+ if (i >= newData.length) {
1131
+ //item减少需要布局改变
1132
+ layoutChange = true;
1133
+ break;
1134
+ } else {
1135
+ //数据中存在undefined item
1136
+ throw new Error("undefined item in data list.", i, newData);
1137
+ }
984
1138
  }
985
1139
  }
986
1140
  }
987
1141
  }
988
1142
 
989
- //记录刷新前焦点的可视状态, 若焦点可视, 则刷新后也需要保证焦点的可视
990
- let needSlide = false;
991
- if (slideToFocus == "enable") {
992
- needSlide = true;
993
- } else if (slideToFocus == "disable") {
994
- needSlide = false;
995
- } else {
996
- let targetRect = mRectCache.getCurRect() ?? mRectCache.getPreRect();
997
- if (targetRect) {
998
- needSlide = rectVisibleState(targetRect) !== 0;
999
- } else {
1000
- needSlide = rectVisibleState(getItemById(focusId)?.templateInfo) !== 0;
1001
- }
1143
+ // 刷新数据时, 重置gazeIndex
1144
+ if (forceUpdate || curFocusItemChanged || targetFocusId != focusId) {
1145
+ gazeIndex = -1;
1002
1146
  }
1003
-
1147
+ //更新template
1004
1148
  dataList = newData;
1005
- dataKeyList = dataList.map(i => i[DATA_ID_KEY]);
1006
-
1149
+ dataKeyList = dataList.map((i) => i[DATA_ID_KEY]);
1007
1150
  if (forceUpdate || layoutChange) {
1008
1151
  //需要更新布局
1009
1152
  pageUpdateToken.value++;
@@ -1026,16 +1169,16 @@ export const setup = (
1026
1169
  props.name,
1027
1170
  _onTemplateAddDone
1028
1171
  );
1029
- if (props.onScroll) {
1172
+ if (props.onScroll || props.touchFlag > 0) {
1030
1173
  templateItemAdder.tryAddItemByIndex(dataList.length - 1);
1031
1174
  } else {
1032
1175
  templateItemAdder.tryAddItemById(targetFocusId);
1033
1176
  }
1034
1177
  } else {
1178
+ templateItemAdder.updateData(newData);
1035
1179
  if (maxSameIndex < newData.length - 1) {
1036
1180
  //追加数据
1037
- templateItemAdder.updateData(newData);
1038
- if (props.onScroll) {
1181
+ if (props.onScroll || props.touchFlag > 0) {
1039
1182
  templateItemAdder.tryAddItemByIndex(dataList.length - 1);
1040
1183
  } else {
1041
1184
  templateItemAdder.tryAddItemById(targetFocusId);
@@ -1046,7 +1189,10 @@ export const setup = (
1046
1189
  if (onlyDataChangeList.length > 0) {
1047
1190
  for (let i of onlyDataChangeList) {
1048
1191
  if (i.index < innerData.length) {
1049
- innerData[i.index].updateCustomData(i.data, _getItemConfigFromMeasursObj(i.measureObj));
1192
+ innerData[i.index].updateCustomData(
1193
+ i.data,
1194
+ _getItemConfigFromMeasursObj(i.measureObj)
1195
+ );
1050
1196
  innerData[i.index].enableTap = i.measureObj.enableTap ?? false;
1051
1197
  } else {
1052
1198
  //之后的数据未布局, 尚未添加到innerData中
@@ -1055,16 +1201,7 @@ export const setup = (
1055
1201
  }
1056
1202
  }
1057
1203
  }
1058
-
1059
- if (targetFocusId != focusId) {
1060
- //重置所有的滚动信息
1061
- _changeFocusId(targetFocusId, false);
1062
- visibleInfo = visibleInfo.copy();
1063
- visibleInfo.start = 0;
1064
- visibleInfo._startMax = 0;
1065
- slideDivLeft.value = 0;
1066
- slideDivTop.value = 0;
1067
- }
1204
+ //更新可视
1068
1205
  const updater = pageUpdater.update(
1069
1206
  metroTemplate,
1070
1207
  visibleInfo.startWithPadding - innerKeepTraceRange * pageRange,
@@ -1074,22 +1211,71 @@ export const setup = (
1074
1211
  permanentItemList
1075
1212
  );
1076
1213
  updater.apply();
1077
- const focusItem = getItemById(focusId);
1078
- onItemFocus(focusItem, null);
1079
- if (needSlide) {
1080
- if (targetRect) {
1081
- slideToRectInner(targetRect, false, 0, true);
1082
- } else if (focusItem.itemConfig.itemSlide == METRO_WIDGET_CONST.ITEM_SLIDE.ACT_ITEM_FOCUS) {
1083
- //只有这个item是控制滚动的才slide, 其他如嵌套时不需要slide
1084
- slideToItemInner(id2Index(focusId), false, 0, 0, true);
1214
+
1215
+ //其他处理
1216
+ if (mode.getMode() == TOUCH_MODE) {
1217
+ //TODO touch模式的refresh还是有问题,
1218
+ // 1. 点击删除item, 会触发onDragStart, 这里onDragStart正好更新了visibleInfo.start导致可以运行, 但这里还是要正确更新visibleInfo.start
1219
+ // let divPos = vertical ? slideDivTop.value + freeMoveSlideGapTop : slideDivLeft.value + freeMoveSlideGapLeft;
1220
+ // visibleInfo.start = getVisibleStart(data);
1221
+ } else {
1222
+ //非触控模式的更新处理
1223
+ //记录刷新前焦点的可视状态, 若焦点可视, 则刷新后也需要保证焦点的可视
1224
+ let needSlide = false;
1225
+ let targetRect = mRectCache.getCurRect() ?? mRectCache.getPreRect();
1226
+ if (targetFocusId != focusId) {
1227
+ needSlide = true;
1228
+ } else if (slideToFocus == "enable") {
1229
+ needSlide = true;
1230
+ } else if (slideToFocus == "disable") {
1231
+ needSlide = false;
1232
+ } else {
1233
+ if (targetRect) {
1234
+ needSlide = rectVisibleState(targetRect) !== 0;
1235
+ } else {
1236
+ needSlide =
1237
+ rectVisibleState(getItemById(focusId)?.templateInfo) !== 0;
1085
1238
  }
1239
+ }
1240
+ if (targetFocusId != focusId) {
1241
+ //由于template add done 回调里会更新box, 需要在template重新创建前, 重置所有的滚动信息
1242
+ visibleInfo = visibleInfo.copy();
1243
+ visibleInfo.start = 0;
1244
+ visibleInfo._startMax = 0;
1245
+ slideDivLeft.value = 0;
1246
+ slideDivTop.value = 0;
1247
+ }
1248
+
1249
+ if (targetFocusId != focusId) {
1250
+ //重置所有的滚动信息
1251
+ _changeFocusId(targetFocusId, false);
1252
+ }
1253
+
1254
+ const focusItem = getItemById(focusId);
1255
+ if (focusItem) {
1256
+ //数据刷新时, 重置preEdgeRect, 否则再嵌套模式下, 会使用上一次的preEdgeRect, 导致子又findNearestByRect
1257
+ preEdgeRect = null;
1258
+ onItemFocus(focusItem, null);
1259
+ if (needSlide) {
1260
+ if (targetRect) {
1261
+ slideToRectInner(targetRect, false, 0, true);
1262
+ } else if (
1263
+ focusItem.itemConfig.itemSlide ==
1264
+ METRO_WIDGET_CONST.ITEM_SLIDE.ACT_ITEM_FOCUS
1265
+ ) {
1266
+ //只有这个item是控制滚动的才slide, 其他如嵌套时不需要slide
1267
+ slideToItemInner(id2Index(focusId), false, 0, 0, true);
1268
+ }
1269
+ }
1270
+ } else {
1271
+ slideToInner(0, false);
1272
+ preEdgeRect = null;
1273
+ mRectCache.clean();
1274
+ }
1086
1275
  }
1087
-
1088
- //template和slideDivStyle均确定后再次重设box condition
1089
- updateTouchBoxCondition();
1090
1276
  }
1091
1277
  } catch (e) {
1092
- console.log(TAG, "refresh error", e)
1278
+ console.log(TAG, "refresh error", e);
1093
1279
  }
1094
1280
  };
1095
1281
 
@@ -1107,16 +1293,34 @@ export const setup = (
1107
1293
  };
1108
1294
 
1109
1295
  const moveFocus = (direction) => {
1110
- if (innerData.length <= 0) { return; }
1296
+ if (innerData.length <= 0) {
1297
+ return;
1298
+ }
1111
1299
  //有外部触发的滚动时, 取消load
1112
1300
  tryCancelDelayLoad();
1113
- if (direction == "left" || direction == 37 || direction == EdgeDirection.left) {
1301
+ if (
1302
+ direction == "left" ||
1303
+ direction == 37 ||
1304
+ direction == EdgeDirection.left
1305
+ ) {
1114
1306
  _moveToNext(-1, 0);
1115
- } else if (direction == "right" || direction == 39 || direction == EdgeDirection.right) {
1307
+ } else if (
1308
+ direction == "right" ||
1309
+ direction == 39 ||
1310
+ direction == EdgeDirection.right
1311
+ ) {
1116
1312
  _moveToNext(1, 0);
1117
- } else if (direction == "top" || direction == 38 || direction == EdgeDirection.top) {
1313
+ } else if (
1314
+ direction == "top" ||
1315
+ direction == 38 ||
1316
+ direction == EdgeDirection.top
1317
+ ) {
1118
1318
  _moveToNext(0, -1);
1119
- } else if (direction == "bottom" || direction == 40 || direction == EdgeDirection.bottom) {
1319
+ } else if (
1320
+ direction == "bottom" ||
1321
+ direction == 40 ||
1322
+ direction == EdgeDirection.bottom
1323
+ ) {
1120
1324
  _moveToNext(0, 1);
1121
1325
  } else {
1122
1326
  console.error(TAG, "moveFocus direction is invalid.", direction);
@@ -1125,23 +1329,23 @@ export const setup = (
1125
1329
 
1126
1330
  const getCustomerDataSize = () => {
1127
1331
  return dataList.length;
1128
- }
1332
+ };
1129
1333
 
1130
1334
  const getCurrentFocusIndex = () => {
1131
1335
  return id2Index(focusId);
1132
- }
1336
+ };
1133
1337
 
1134
1338
  const getTemplatePosition = (index) => {
1135
1339
  return _getTemplatePosition(index);
1136
- }
1340
+ };
1137
1341
 
1138
1342
  const lockSlide = () => {
1139
1343
  slideLock = true;
1140
- }
1344
+ };
1141
1345
 
1142
1346
  const unlockSlide = () => {
1143
1347
  slideLock = false;
1144
- }
1348
+ };
1145
1349
 
1146
1350
  const setSlideSetting = (setting) => {
1147
1351
  if (!setting) {
@@ -1149,14 +1353,14 @@ export const setup = (
1149
1353
  } else {
1150
1354
  innerSlideSetting = setting;
1151
1355
  }
1152
- }
1356
+ };
1153
1357
 
1154
1358
  const tryCancelDelayLoad = () => {
1155
1359
  if (delayLoadHandler > 0) {
1156
1360
  clearTimeout(delayLoadHandler);
1157
1361
  delayLoadHandler = -1;
1158
1362
  }
1159
- }
1363
+ };
1160
1364
 
1161
1365
  const exportObject = {
1162
1366
  lockSlide,
@@ -1232,16 +1436,14 @@ export const setup = (
1232
1436
  let full_show =
1233
1437
  itemTemplateInfo[key_pos] >= visibleInfo.start &&
1234
1438
  itemTemplateInfo[key_pos] + itemTemplateInfo[key_width] - 1 <=
1235
- visibleInfo.end;
1439
+ visibleInfo.end;
1236
1440
  if (full_show) {
1237
- let x_pos =
1238
- vertical
1239
- ? itemTemplateInfo.left
1240
- : itemTemplateInfo.left - visibleInfo.start;
1241
- let y_pos =
1242
- vertical
1243
- ? itemTemplateInfo.top - visibleInfo.start
1244
- : itemTemplateInfo.top;
1441
+ let x_pos = vertical
1442
+ ? itemTemplateInfo.left
1443
+ : itemTemplateInfo.left - visibleInfo.start;
1444
+ let y_pos = vertical
1445
+ ? itemTemplateInfo.top - visibleInfo.start
1446
+ : itemTemplateInfo.top;
1245
1447
  var target_x_range = new SingleRangeModel(
1246
1448
  x_pos,
1247
1449
  x_pos + itemTemplateInfo.width - 1
@@ -1381,21 +1583,29 @@ export const setup = (
1381
1583
 
1382
1584
  const onDispatchKeyDown = (ev) => {
1383
1585
  if (mode.getMode() == TOUCH_MODE && !mode.duringTouch()) {
1384
- if (ev.keyCode == 37 || ev.keyCode == 38 || ev.keyCode == 39 || ev.keyCode == 40) {
1586
+ if (
1587
+ ev.keyCode == 37 ||
1588
+ ev.keyCode == 38 ||
1589
+ ev.keyCode == 39 ||
1590
+ ev.keyCode == 40
1591
+ ) {
1385
1592
  //只有在上下左右键切换为focus_mode
1386
1593
  mode.keyDown();
1387
1594
  //touch切换为focus的首次按键只显示焦点
1388
1595
  const focusItem = _getVisibleFocusableItem();
1389
- const preFocusItem = getItemById(focusId);
1390
- _changeFocusId(focusItem.id, false);
1391
- if (preFocusItem.id !== focusItem.id) {
1392
- onItemBlur(preFocusItem);
1596
+ if (focusItem) {
1597
+ const preFocusItem = getItemById(focusId);
1598
+ _changeFocusId(focusItem.id, false);
1599
+ if (preFocusItem.id !== focusItem.id) {
1600
+ onItemBlur(preFocusItem);
1601
+ }
1602
+ onItemFocus(focusItem);
1393
1603
  }
1394
- onItemFocus(focusItem);
1604
+ return true;
1395
1605
  }
1396
1606
  }
1397
1607
  return false;
1398
- }
1608
+ };
1399
1609
 
1400
1610
  const _moveByKey = (keyCode) => {
1401
1611
  switch (keyCode) {
@@ -1414,13 +1624,14 @@ export const setup = (
1414
1624
  default:
1415
1625
  return false;
1416
1626
  }
1417
- }
1627
+ };
1418
1628
 
1419
1629
  let clickDownReceived = false;
1420
1630
  let longPressTriggered = false;
1421
1631
 
1422
1632
  const focusBlockOnKeyUp = (ev) => {
1423
- if (!props.enableLongPress) {
1633
+ const curFocusItem = getItemById(focusId);
1634
+ if (!curFocusItem || !curFocusItem.itemConfig.enableLongPress) {
1424
1635
  return false;
1425
1636
  }
1426
1637
  //支持长按时 onClick 由 keyup 处理
@@ -1429,14 +1640,14 @@ export const setup = (
1429
1640
  if (!longPressTriggered) {
1430
1641
  if (ev.keyCode == 13 && clickDownReceived) {
1431
1642
  clickDownReceived = false;
1432
- onItemClick(getItemById(focusId));
1643
+ onItemClick(curFocusItem);
1433
1644
  return true;
1434
1645
  }
1435
1646
  } else {
1436
1647
  longPressTriggered = false;
1437
1648
  }
1438
1649
  return false;
1439
- }
1650
+ };
1440
1651
 
1441
1652
  let preStartKeyDownTime = -1;
1442
1653
  const focusBlockOnKeyDown = (ev) => {
@@ -1459,14 +1670,19 @@ export const setup = (
1459
1670
  return true;
1460
1671
  }
1461
1672
  if (ev.keyCode == 13) {
1673
+ const curFocusItem = getItemById(focusId);
1462
1674
  clickDownReceived = true;
1463
- if (props.enableLongPress) {
1464
- if (ev.repeat && ev.timeStamp - preStartKeyDownTime > LONGPRESS_TIMEOUT && !longPressTriggered) {
1675
+ if (curFocusItem.itemConfig.enableLongPress) {
1676
+ if (
1677
+ ev.repeat &&
1678
+ ev.timeStamp - preStartKeyDownTime > LONGPRESS_TIMEOUT &&
1679
+ !longPressTriggered
1680
+ ) {
1465
1681
  longPressTriggered = true;
1466
- onItemLongPress(getItemById(focusId));
1682
+ onItemLongPress(curFocusItem);
1467
1683
  }
1468
1684
  } else if (!ev.repeat) {
1469
- onItemClick(getItemById(focusId));
1685
+ onItemClick(curFocusItem);
1470
1686
  }
1471
1687
  return true;
1472
1688
  } else {
@@ -1482,7 +1698,8 @@ export const setup = (
1482
1698
  if (lastTemplateInfo) {
1483
1699
  if (vertical) {
1484
1700
  touchDivSize.width = props.width;
1485
- touchDivSize.height = lastTemplateInfo.top + lastTemplateInfo.height - 1;
1701
+ touchDivSize.height =
1702
+ lastTemplateInfo.top + lastTemplateInfo.height - 1;
1486
1703
  } else {
1487
1704
  touchDivSize.width = lastTemplateInfo.left + lastTemplateInfo.width - 1;
1488
1705
  touchDivSize.height = props.height;
@@ -1498,7 +1715,7 @@ export const setup = (
1498
1715
  if (preTouchW !== touchDivSize.width || preTouchH !== touchDivSize.height) {
1499
1716
  updateTouchBoxCondition();
1500
1717
  }
1501
- }
1718
+ };
1502
1719
 
1503
1720
  const _getItemConfigFromMeasursObj = (measuresObj) => {
1504
1721
  let focusZIndex = -1,
@@ -1523,10 +1740,12 @@ export const setup = (
1523
1740
  focusZIndex,
1524
1741
  normalZIndex,
1525
1742
  permanent: measuresObj.permanent ?? false,
1526
- itemSlide: measuresObj.itemSlide ?? METRO_WIDGET_CONST.ITEM_SLIDE.ACT_ITEM_FOCUS,
1743
+ itemSlide:
1744
+ measuresObj.itemSlide ?? METRO_WIDGET_CONST.ITEM_SLIDE.ACT_ITEM_FOCUS,
1527
1745
  showSkeleton: measuresObj.showSkeleton ?? true,
1746
+ enableLongPress: measuresObj.enableLongPress ?? props.enableLongPress,
1528
1747
  };
1529
- }
1748
+ };
1530
1749
 
1531
1750
  const _onTemplateItemAdd = (customerData, templateItem, measuresObj) => {
1532
1751
  let itemConfig = _getItemConfigFromMeasursObj(measuresObj);
@@ -1562,10 +1781,31 @@ export const setup = (
1562
1781
  slideTo: slideTo,
1563
1782
  updateItemSize,
1564
1783
  widgetHandler: exportObject,
1784
+ },
1785
+ {
1786
+ onTap: onItemTap,
1565
1787
  }
1566
1788
  );
1567
1789
  item.enableTap = measuresObj.enableTap ?? false;
1568
-
1790
+ // 占位图布局
1791
+ if (props.enableItemRenderBreak) {
1792
+ if (measuresObj.placeHolderLayout
1793
+ && typeof measuresObj.placeHolderLayout.left == "number"
1794
+ && typeof measuresObj.placeHolderLayout.top == "number"
1795
+ && typeof measuresObj.placeHolderLayout.width == "number"
1796
+ && typeof measuresObj.placeHolderLayout.height == "number"
1797
+ ) {
1798
+ item.placeHolderLayout = Object.assign({}, measuresObj.placeHolderLayout);
1799
+ } else {
1800
+ item.placeHolderLayout = {
1801
+ left: 0,
1802
+ top: 0,
1803
+ width: item.renderStyle.width - (props.placeHolderSetting.gap ?? 0),
1804
+ height: item.renderStyle.height - (props.placeHolderSetting.gap ?? 0)
1805
+ }
1806
+ }
1807
+ }
1808
+
1569
1809
  innerData.push(item);
1570
1810
  if (item.itemConfig.permanent) {
1571
1811
  permanentItemList.push({
@@ -1596,7 +1836,10 @@ export const setup = (
1596
1836
  return false;
1597
1837
  }
1598
1838
  const focusItem = getItemById(focusId);
1599
- if (focusItem.itemConfig.itemSlide !== METRO_WIDGET_CONST.ITEM_SLIDE.ACT_FOCUS_RECT_EVENT) {
1839
+ if (
1840
+ focusItem.itemConfig.itemSlide !==
1841
+ METRO_WIDGET_CONST.ITEM_SLIDE.ACT_FOCUS_RECT_EVENT
1842
+ ) {
1600
1843
  return;
1601
1844
  }
1602
1845
  let item_div = ev.element;
@@ -1614,7 +1857,9 @@ export const setup = (
1614
1857
  direction = 1;
1615
1858
  }
1616
1859
  }
1617
- const item_layout = item_div.jsvGetRelativePosition(toRaw(locateDiv.value));
1860
+ const item_layout = item_div.jsvGetRelativePosition(
1861
+ toRaw(locateDiv.value)
1862
+ );
1618
1863
 
1619
1864
  let fakeItem = {
1620
1865
  templateInfo: {
@@ -1628,16 +1873,18 @@ export const setup = (
1628
1873
  },
1629
1874
  };
1630
1875
 
1631
- let cur_slide = _calculateVisibleStart(fakeItem.templateInfo, direction, fakeItem.templateInfo, visibleInfo);
1876
+ let cur_slide = _calculateVisibleStart(
1877
+ fakeItem.templateInfo,
1878
+ direction,
1879
+ fakeItem.templateInfo,
1880
+ visibleInfo
1881
+ );
1632
1882
  if (cur_slide != visibleInfo.start) {
1633
- slideToInner(
1634
- cur_slide,
1635
- true,
1636
- {
1637
- //250207 change: 为true时, 会导致不可见的item反复加载,释放, 所以改为false
1638
- //但之前设为true应该是为了保证滚动时的楼层不提前消失, 此后若再遇到这类问题再考虑
1639
- mergeTmp: false
1640
- });
1883
+ slideToInner(cur_slide, true, {
1884
+ //250207 change: 为true时, 会导致不可见的item反复加载,释放, 所以改为false
1885
+ //但之前设为true应该是为了保证滚动时的楼层不提前消失, 此后若再遇到这类问题再考虑
1886
+ mergeTmp: false,
1887
+ });
1641
1888
  return true;
1642
1889
  }
1643
1890
  }
@@ -1646,10 +1893,14 @@ export const setup = (
1646
1893
 
1647
1894
  const _changeFocusId = (id, cache_pre = true) => {
1648
1895
  preFocusId = cache_pre ? focusId : -1;
1649
- focusId = id >= 0 && id < metroTemplate.size ? id : 0;
1650
- currentFocusIndex.value = id2Index(id);
1896
+ if (metroTemplate.size == 0) {
1897
+ focusId = -1;
1898
+ } else {
1899
+ focusId = id >= 0 && id < metroTemplate.size ? id : 0;
1900
+ }
1901
+ currentFocusIndex.value = id2Index(focusId);
1651
1902
  taskManager.addTask(TaskType.ON_FOCUS_CHANGE);
1652
- }
1903
+ };
1653
1904
 
1654
1905
  const _bubbleCustomEvent = (event) => {
1655
1906
  if (props.sendFocusRectEvent && event) {
@@ -1703,8 +1954,10 @@ export const setup = (
1703
1954
  templateItemAdder.tryAddItem(next_focus_item.templateInfo, 1);
1704
1955
 
1705
1956
  // itemFocus 和 itemBlur放在计算visibleStart之前, 以便用户更改template后在计算滚动
1706
- let x_off_set = preFocusItem.templateInfo.left - next_focus_item.templateInfo.left;
1707
- let y_off_set = preFocusItem.templateInfo.top - next_focus_item.templateInfo.top;
1957
+ let x_off_set =
1958
+ preFocusItem.templateInfo.left - next_focus_item.templateInfo.left;
1959
+ let y_off_set =
1960
+ preFocusItem.templateInfo.top - next_focus_item.templateInfo.top;
1708
1961
  if (item_edge_rect && item_edge_rect.rect) {
1709
1962
  item_edge_rect.rect.x += x_off_set;
1710
1963
  item_edge_rect.rect.y += y_off_set;
@@ -1733,12 +1986,16 @@ export const setup = (
1733
1986
  onItemBlur(preFocusItem);
1734
1987
  onItemFocus(next_focus_item, preEdgeRect);
1735
1988
 
1736
- if (next_focus_item.itemConfig.itemSlide == METRO_WIDGET_CONST.ITEM_SLIDE.ACT_ITEM_FOCUS) {
1989
+ if (
1990
+ next_focus_item.itemConfig.itemSlide ==
1991
+ METRO_WIDGET_CONST.ITEM_SLIDE.ACT_ITEM_FOCUS
1992
+ ) {
1737
1993
  slideToItemInner(
1738
1994
  next_focus_item.index,
1739
1995
  true,
1740
1996
  vertical ? vertical_direction : horizontal_direction,
1741
- preFocusItem);
1997
+ preFocusItem
1998
+ );
1742
1999
  } else {
1743
2000
  const updater = pageUpdater.update(
1744
2001
  metroTemplate,
@@ -1769,7 +2026,7 @@ export const setup = (
1769
2026
  edge = EdgeDirection.top;
1770
2027
  }
1771
2028
  const curTemplateInfo = getItemById(focusId)?.templateInfo;
1772
- let rect
2029
+ let rect;
1773
2030
  if (curTemplateInfo) {
1774
2031
  rect = {
1775
2032
  x: curTemplateInfo.left - x_off_set,
@@ -1789,7 +2046,7 @@ export const setup = (
1789
2046
  props.onEdge?.({
1790
2047
  direction: edge,
1791
2048
  rect: rect,
1792
- childEdgeInfo: item_edge_rect
2049
+ childEdgeInfo: item_edge_rect,
1793
2050
  });
1794
2051
  innerData[id2Index(focusId)]?.onWidgetEdge({
1795
2052
  direction: edge,
@@ -1813,23 +2070,32 @@ export const setup = (
1813
2070
  }
1814
2071
  }
1815
2072
  if ((innerSlideSetting.BoundaryProtect & SlideSetting.END_PROTECT) > 0) {
1816
- let lastTemplateInfo = getItemByIndex(metroTemplate.getTailItemIndex()).templateInfo;
2073
+ let lastTemplateInfo = getItemByIndex(
2074
+ metroTemplate.getTailItemIndex()
2075
+ ).templateInfo;
1817
2076
  const lastEnd = lastTemplateInfo[pos_key] + lastTemplateInfo[size_key];
1818
2077
  const lastVisibleStart = Math.max(lastEnd - vInfo.range, 0);
1819
2078
  //边界必须大于等于0, 同时若最后一个缩进时, 边界采用最后一个item的位置
1820
2079
  if (vInfo.end <= lastEnd) {
1821
2080
  let boundary = lastVisibleStart;
1822
- visibleStart = visibleStart > boundary ? lastVisibleStart : visibleStart;
2081
+ visibleStart =
2082
+ visibleStart > boundary ? lastVisibleStart : visibleStart;
1823
2083
  } else {
1824
2084
  // 以最后一个item的位置作为动态的保护边界
1825
2085
  visibleStart = visibleStart > vInfo.start ? vInfo.start : visibleStart;
1826
2086
  }
1827
2087
  }
1828
2088
  return visibleStart;
1829
- }
2089
+ };
1830
2090
 
1831
2091
  const mRectCache = new RectCache();
1832
- const _calculateVisibleStart = (targetRect, _direction, templateInfo, vInfo, preInfo = null) => {
2092
+ const _calculateVisibleStart = (
2093
+ targetRect,
2094
+ _direction,
2095
+ templateInfo,
2096
+ vInfo,
2097
+ preInfo = null
2098
+ ) => {
1833
2099
  if (!targetRect) {
1834
2100
  console.error("MetroWidget: _calculateVisibleStart target item is null");
1835
2101
  return 0;
@@ -1840,7 +2106,7 @@ export const setup = (
1840
2106
  width: targetRect.width,
1841
2107
  height: targetRect.height,
1842
2108
  frameCount: Forge.sFrameCount.count,
1843
- }
2109
+ };
1844
2110
  mRectCache.cache(curRect);
1845
2111
  let preRect = mRectCache.getPreRect();
1846
2112
  if (preInfo) {
@@ -1874,9 +2140,14 @@ export const setup = (
1874
2140
  }
1875
2141
 
1876
2142
  if (needCalculate) {
2143
+ let target = targetRect[pos_key] + targetRect[size_key] / 2;
2144
+ if (innerSlideSetting.Align == "start") {
2145
+ target = targetRect[pos_key];
2146
+ } else if (innerSlideSetting.Align == "end") {
2147
+ target = targetRect[pos_key] + targetRect[size_key];
2148
+ }
1877
2149
  new_visible_start = Math.ceil(
1878
- targetRect[pos_key] + targetRect[size_key] / 2 -
1879
- vInfo.range * innerSlideSetting.FixPercent
2150
+ target - vInfo.range * innerSlideSetting.FixPercent
1880
2151
  );
1881
2152
  }
1882
2153
  break;
@@ -1914,14 +2185,19 @@ export const setup = (
1914
2185
 
1915
2186
  if (preRect) {
1916
2187
  const rect0Start = vInfo.start;
1917
- const rect0End = vInfo.start + vInfo.range * innerSlideSetting.StartPercent;
1918
- const rect0Range = rect0End - rect0Start + 1
1919
- const rect1Start = vInfo.start + vInfo.range * innerSlideSetting.EndPercent;
2188
+ const rect0End =
2189
+ vInfo.start + vInfo.range * innerSlideSetting.StartPercent;
2190
+ const rect0Range = rect0End - rect0Start + 1;
2191
+ const rect1Start =
2192
+ vInfo.start + vInfo.range * innerSlideSetting.EndPercent;
1920
2193
  const rect1End = vInfo.start + vInfo.range - 1;
1921
2194
  const rect1Range = rect1End - rect1Start + 1;
1922
2195
 
1923
2196
  let target0 = Math.min(preRect[pos_key], rect0End);
1924
- let target1 = Math.max(preRect[pos_key] + preRect[size_key] - 1, rect1Start);
2197
+ let target1 = Math.max(
2198
+ preRect[pos_key] + preRect[size_key] - 1,
2199
+ rect1Start
2200
+ );
1925
2201
 
1926
2202
  let rect0Result = undefined;
1927
2203
  let rect1Result = undefined;
@@ -1934,7 +2210,7 @@ export const setup = (
1934
2210
  } else {
1935
2211
  if (direction <= 0) {
1936
2212
  //inRect0, 只处理往左/往上
1937
- rect0Result = vInfo.start + (itemStart - target0)
2213
+ rect0Result = vInfo.start + (itemStart - target0);
1938
2214
  }
1939
2215
  }
1940
2216
  }
@@ -1952,7 +2228,10 @@ export const setup = (
1952
2228
  }
1953
2229
  }
1954
2230
 
1955
- if (typeof rect0Result !== "undefined" && typeof rect1Result !== "undefined") {
2231
+ if (
2232
+ typeof rect0Result !== "undefined" &&
2233
+ typeof rect1Result !== "undefined"
2234
+ ) {
1956
2235
  //重叠区域
1957
2236
  new_visible_start = rect0Result;
1958
2237
  } else if (typeof rect0Result !== "undefined") {
@@ -1967,11 +2246,16 @@ export const setup = (
1967
2246
  const tailSafeArea = innerSlideSetting.TailSafeArea * vInfo.range;
1968
2247
  if (itemMainSize > vInfo.range - headSafeArea - tailSafeArea) {
1969
2248
  // 大item
1970
- new_visible_start = Math.round(itemStart - (vInfo.range - itemMainSize) / 2)
2249
+ new_visible_start = Math.round(
2250
+ itemStart - (vInfo.range - itemMainSize) / 2
2251
+ );
1971
2252
  } else {
1972
2253
  if (itemStart < new_visible_start + headSafeArea) {
1973
2254
  new_visible_start = itemStart - headSafeArea;
1974
- } else if (itemEnd > new_visible_start + vInfo.range - 1 - tailSafeArea) {
2255
+ } else if (
2256
+ itemEnd >
2257
+ new_visible_start + vInfo.range - 1 - tailSafeArea
2258
+ ) {
1975
2259
  new_visible_start = itemEnd - vInfo.range + tailSafeArea;
1976
2260
  }
1977
2261
  }
@@ -1984,7 +2268,12 @@ export const setup = (
1984
2268
  );
1985
2269
  }
1986
2270
 
1987
- new_visible_start = normalizeVisibleStart(new_visible_start, targetRect, templateInfo?.index, vInfo);
2271
+ new_visible_start = normalizeVisibleStart(
2272
+ new_visible_start,
2273
+ targetRect,
2274
+ templateInfo?.index,
2275
+ vInfo
2276
+ );
1988
2277
  return Math.round(new_visible_start);
1989
2278
  };
1990
2279
 
@@ -2021,12 +2310,13 @@ export const setup = (
2021
2310
  return;
2022
2311
  }
2023
2312
 
2024
- let focus_id =
2313
+ let focus_id = index2Id(gazeIndex);
2314
+ focus_id =
2025
2315
  typeof enterFocusId !== "undefined" &&
2026
- enterFocusId >= 0 &&
2027
- enterFocusId < metroTemplate.size
2316
+ enterFocusId >= 0 &&
2317
+ enterFocusId < metroTemplate.size
2028
2318
  ? enterFocusId
2029
- : focusId;
2319
+ : focus_id;
2030
2320
  focus_id = _ifValidEnterRect(enterFocusRect)
2031
2321
  ? _calculateNearestItemByRect(pageUpdater.getRange(), enterFocusRect)
2032
2322
  : focus_id;
@@ -2034,7 +2324,7 @@ export const setup = (
2034
2324
  _changeFocusId(focus_id, false);
2035
2325
  enterFocusId = -1;
2036
2326
  enterFocusRect = null;
2037
- firstOnItemFocusCalled = onItemFocus(getItemById(focusId), preEdgeRect);;
2327
+ firstOnItemFocusCalled = onItemFocus(getItemById(focusId), preEdgeRect);
2038
2328
  props.onFocus?.();
2039
2329
  };
2040
2330
 
@@ -2046,19 +2336,21 @@ export const setup = (
2046
2336
  onItemBlur(getItemById(preFocusId));
2047
2337
  props.onBlur?.();
2048
2338
  isFocus = false;
2049
- mRectCache.clean()
2339
+ mRectCache.clean();
2050
2340
  };
2051
2341
 
2052
2342
  const _updatePage = (rangeSet) => {
2053
2343
  let cur = id2Index(focusId);
2054
2344
  if (cur >= 0) {
2055
- rangeSet.add(cur)
2345
+ rangeSet.add(cur);
2056
2346
  }
2057
2347
  const tmpArray = Array.from(rangeSet);
2058
2348
  let newArray = tmpArray.map((item) => {
2059
2349
  return getItemByIndex(item);
2060
2350
  });
2061
- const newItemList = newArray.filter((i) => { return !renderData.value?.includes(i) });
2351
+ const newItemList = newArray.filter((i) => {
2352
+ return !renderData.value?.includes(i);
2353
+ });
2062
2354
  renderData.value = newArray;
2063
2355
  if (props.enableItemRenderBreak) {
2064
2356
  itemRender.value = false;
@@ -2074,18 +2366,25 @@ export const setup = (
2074
2366
  };
2075
2367
 
2076
2368
  const _getVisibleFocusableItem = () => {
2077
- const focusItem = getItemById(focusId);
2369
+ let item = getItemByIndex(gazeIndex);
2370
+ if (rectVisibleState(item.templateInfo) == 2) {
2371
+ return item;
2372
+ }
2373
+ item = getItemById(focusId);
2078
2374
  if (rectVisibleState(focusItem.templateInfo) == 2) {
2079
2375
  return focusItem;
2080
- } else {
2081
- //遍历renderList, 找到第一个可见的 focusable item
2082
- for (let item of renderData.value) {
2083
- if (item.templateInfo.focusable && rectVisibleState(item.templateInfo) == 2) {
2084
- return item;
2085
- }
2376
+ }
2377
+ //遍历renderList, 找到第一个可见的 focusable item
2378
+ for (let item of renderData.value) {
2379
+ if (
2380
+ item.templateInfo.focusable &&
2381
+ rectVisibleState(item.templateInfo) == 2
2382
+ ) {
2383
+ return item;
2086
2384
  }
2087
2385
  }
2088
- }
2386
+ return null;
2387
+ };
2089
2388
 
2090
2389
  const _onScroll = () => {
2091
2390
  if (props.onScroll) {
@@ -2117,13 +2416,15 @@ export const setup = (
2117
2416
  let onMoveSensitivity = -1;
2118
2417
 
2119
2418
  const getVisibleStart = (moveInfo) => {
2120
- divPos = vertical ? slideDivTop.value + freeMoveSlideGapTop : slideDivLeft.value + freeMoveSlideGapLeft;
2419
+ divPos = vertical
2420
+ ? slideDivTop.value + freeMoveSlideGapTop
2421
+ : slideDivLeft.value + freeMoveSlideGapLeft;
2121
2422
  if (vertical) {
2122
2423
  return -(divPos + Math.round(moveInfo.yPos));
2123
2424
  } else {
2124
2425
  return -(divPos + Math.round(moveInfo.xPos));
2125
2426
  }
2126
- }
2427
+ };
2127
2428
 
2128
2429
  function onSensor(pos) {
2129
2430
  const lastTemplateInfo = getItemByIndex(
@@ -2138,7 +2439,9 @@ export const setup = (
2138
2439
  }
2139
2440
  }
2140
2441
  props.onScroll?.(
2141
- vertical ? -(pos.yPos + slideDivTop.value + freeMoveSlideGapTop) : -(pos.xPos + slideDivLeft.value + freeMoveSlideGapLeft),
2442
+ vertical
2443
+ ? -(pos.yPos + slideDivTop.value + freeMoveSlideGapTop)
2444
+ : -(pos.xPos + slideDivLeft.value + freeMoveSlideGapLeft),
2142
2445
  visibleInfo.range,
2143
2446
  totalWidth
2144
2447
  );
@@ -2156,7 +2459,9 @@ export const setup = (
2156
2459
  }
2157
2460
 
2158
2461
  function setSensorSensitivity(sensitivity = DEFAULT_SENSITIVITY) {
2159
- if (!actorController) { return }
2462
+ if (!actorController) {
2463
+ return;
2464
+ }
2160
2465
  if (sensitivity <= 0) {
2161
2466
  actorController.run((cmds) => [
2162
2467
  cmds.state().removeConditionByGroup(ScensorCondigionGroup),
@@ -2165,11 +2470,10 @@ export const setup = (
2165
2470
  }
2166
2471
 
2167
2472
  if (sensitivity != onMoveSensitivity) {
2168
- setOnMovement(sensitivity)
2473
+ setOnMovement(sensitivity);
2169
2474
  }
2170
2475
  }
2171
2476
 
2172
-
2173
2477
  const getTouchCount = (nexusCustomData) => {
2174
2478
  let touchCount = -1;
2175
2479
  if (nexusCustomData) {
@@ -2180,7 +2484,7 @@ export const setup = (
2180
2484
  }
2181
2485
  }
2182
2486
  return touchCount;
2183
- }
2487
+ };
2184
2488
 
2185
2489
  const mergeTouchSlideToSlideDiv = (touchCount) => {
2186
2490
  let originSlideDivTop = slideDivTop.value;
@@ -2192,24 +2496,28 @@ export const setup = (
2192
2496
  }
2193
2497
  let newSlideGapTop = originSlideDivTop - slideDivTop.value;
2194
2498
  let newSlideGapLeft = originSlideDivLeft - slideDivLeft.value;
2195
- freeMoveSlideGapTop += newSlideGapTop; // 累计slider变化的gap,等待同步完毕时消除gap
2499
+ freeMoveSlideGapTop += newSlideGapTop; // 累计slider变化的gap,等待同步完毕时消除gap
2196
2500
  freeMoveSlideGapLeft += newSlideGapLeft;
2197
2501
 
2198
2502
  const walls = getTouchWall();
2199
2503
  actorController.run((cmds) => [
2200
2504
  cmds.state().removeConditionByGroup(wallConditionGroup),
2201
- cmds.condition(wallConditionGroup, true)
2505
+ cmds
2506
+ .condition(wallConditionGroup, true)
2202
2507
  .boxPosition(walls.left, walls.top, walls.right, walls.bottom)
2203
2508
  .then([cmds.state().setHitWallOverflow()]), //TODO 通过prop设置哪个方向overflow
2204
2509
  cmds.state().setStartOffsetPos(newSlideGapLeft, newSlideGapTop), // 将div的位置调整回馈给FreeMove计量系统
2205
- cmds.condition().onNextTick(0).then([
2206
- SliderEditFuncReOrderWrap(() => {
2207
- freeMoveSlideGapTop -= newSlideGapTop;
2208
- freeMoveSlideGapLeft -= newSlideGapLeft;
2209
- }, true) // Slide调整回调要放在其他事件之前,调整slide的gap值
2210
- ])
2510
+ cmds
2511
+ .condition()
2512
+ .onNextTick(0)
2513
+ .then([
2514
+ SliderEditFuncReOrderWrap(() => {
2515
+ freeMoveSlideGapTop -= newSlideGapTop;
2516
+ freeMoveSlideGapLeft -= newSlideGapLeft;
2517
+ }, true), // Slide调整回调要放在其他事件之前,调整slide的gap值
2518
+ ]),
2211
2519
  ]);
2212
- }
2520
+ };
2213
2521
  function onTouchActionDone(touchCount) {
2214
2522
  //一次触控动作结束
2215
2523
  mergeTouchSlideToSlideDiv(touchCount);
@@ -2236,20 +2544,30 @@ export const setup = (
2236
2544
  right: vertical ? undefined : lockThreshhold,
2237
2545
  top: vertical ? lockThreshhold : undefined,
2238
2546
  bottom: vertical ? lockThreshhold : undefined,
2239
- }
2547
+ };
2240
2548
 
2241
2549
  let passDownTouchInfo = nexusCustomData;
2242
2550
  actorController.run((cmds) => [
2243
2551
  cmds
2244
2552
  .condition(TouchDownConditionGroup, false)
2245
- .offsetPosition(offsetThreshold.left, offsetThreshold.top, offsetThreshold.right, offsetThreshold.bottom)
2553
+ .offsetPosition(
2554
+ offsetThreshold.left,
2555
+ offsetThreshold.top,
2556
+ offsetThreshold.right,
2557
+ offsetThreshold.bottom
2558
+ )
2246
2559
  .then([
2247
- cmds.state().touchLockSwitch(true, vertical ? 1 : 2, unlockThreshold)]),
2560
+ cmds.state().touchLockSwitch(true, vertical ? 1 : 2, unlockThreshold),
2561
+ ]),
2248
2562
  cmds
2249
2563
  .condition(TouchDownConditionGroup, false)
2250
2564
  .startMove(true, true)
2251
- .then([SliderEditFuncReOrderWrap((d) => { onDragStart(d, null, passDownTouchInfo) })]),
2252
- ])
2565
+ .then([
2566
+ SliderEditFuncReOrderWrap((d) => {
2567
+ onDragStart(d, null, passDownTouchInfo);
2568
+ }),
2569
+ ]),
2570
+ ]);
2253
2571
 
2254
2572
  //blur item
2255
2573
  // onItemBlur(getItemById(focusId));
@@ -2269,26 +2587,32 @@ export const setup = (
2269
2587
  //创建锚点
2270
2588
  const anchorArea = 2 * Forge.sRenderBridge.GetScreenInfo().designedWidth;
2271
2589
  let anchorPosList = [];
2272
- let anchorSpacing = visibleInfo.range * 2 / 3;
2590
+ let anchorSpacing = (visibleInfo.range * 2) / 3;
2273
2591
  let anchorPos = anchorSpacing;
2274
2592
  while (anchorPos < anchorArea) {
2275
2593
  anchorPosList.push(-visibleInfo.start + anchorPos);
2276
- anchorPosList.push(-visibleInfo.start - visibleInfo.range - anchorPos + 1);
2594
+ anchorPosList.push(
2595
+ -visibleInfo.start - visibleInfo.range - anchorPos + 1
2596
+ );
2277
2597
  anchorPos += anchorSpacing;
2278
2598
  }
2279
2599
  actorController.run((cmds) => {
2280
- const reachConditionList = anchorPosList.map(pos => {
2600
+ const reachConditionList = anchorPosList.map((pos) => {
2281
2601
  return cmds
2282
2602
  .condition(reachAnchorGroup)
2283
2603
  .reachPosition(pos, undefined)
2284
- .then([SliderEditFuncReOrderWrap((data) => { updateRenderItems(true, true) })])
2285
- })
2604
+ .then([
2605
+ SliderEditFuncReOrderWrap((data) => {
2606
+ updateRenderItems(true, true);
2607
+ }),
2608
+ ]);
2609
+ });
2286
2610
  reachConditionList.unshift(
2287
- cmds.state().removeConditionByGroup(reachAnchorGroup),
2288
- )
2289
- return reachConditionList
2611
+ cmds.state().removeConditionByGroup(reachAnchorGroup)
2612
+ );
2613
+ return reachConditionList;
2290
2614
  });
2291
- }
2615
+ };
2292
2616
 
2293
2617
  const onTouchRelease = (touchCount) => {
2294
2618
  if (mode.getTouchState() == TouchState.TAP) {
@@ -2299,14 +2623,14 @@ export const setup = (
2299
2623
  if (touchRecorder.moved && !mode.duringFling()) {
2300
2624
  onTouchActionDone(touchRecorder.touchCount);
2301
2625
  updateRenderItems(false, false);
2302
- mode.touchEnd(touchCount)
2626
+ mode.touchEnd(touchCount);
2303
2627
  }
2304
2628
  }
2305
2629
  actorController.run((cmds) => [
2306
2630
  cmds.state().removeConditionByGroup(TouchDownConditionGroup),
2307
- cmds.state().touchLockSwitch(false, vertical ? 1 : 2)
2308
- ])
2309
- }
2631
+ cmds.state().touchLockSwitch(false, vertical ? 1 : 2),
2632
+ ]);
2633
+ };
2310
2634
 
2311
2635
  const exportOnTouchRelease = props.touchFlag > 0 ? onTouchRelease : undefined;
2312
2636
 
@@ -2315,10 +2639,10 @@ export const setup = (
2315
2639
  touchRecorder.move();
2316
2640
  if (!(mode.getTouchCount() == touchCount && mode.duringFling())) {
2317
2641
  //dragStart event may be triggered after fling event because of sending it when startMove condition is satisfied
2318
- mode.dragStart(touchCount)
2642
+ mode.dragStart(touchCount);
2319
2643
  }
2320
2644
  visibleInfo.start = getVisibleStart(data);
2321
- }
2645
+ };
2322
2646
 
2323
2647
  const onDragEnd = (data, customData, nexusCustomData) => {
2324
2648
  let touchCount = getTouchCount(nexusCustomData);
@@ -2327,7 +2651,7 @@ export const setup = (
2327
2651
  actorController.run((cmds) => [
2328
2652
  cmds.state().removeConditionByGroup(reachAnchorGroup),
2329
2653
  ]);
2330
- }
2654
+ };
2331
2655
 
2332
2656
  const onFlingStart = (data, customData, nexusCustomData) => {
2333
2657
  let touchCount = getTouchCount(nexusCustomData);
@@ -2335,13 +2659,13 @@ export const setup = (
2335
2659
  mode.flingStart(touchCount);
2336
2660
  visibleInfo.start = getVisibleStart(data);
2337
2661
  updateRenderItems(true, true);
2338
- }
2662
+ };
2339
2663
 
2340
2664
  const onFlingProgress = (data, customData, nexusCustomData) => {
2341
2665
  let touchCount = getTouchCount(nexusCustomData);
2342
2666
  visibleInfo.start = getVisibleStart(data);
2343
2667
  updateRenderItems(true, true);
2344
- }
2668
+ };
2345
2669
 
2346
2670
  const onFlingEnd = (data, customData, nexusCustomData) => {
2347
2671
  visibleInfo.start = getVisibleStart(data);
@@ -2353,12 +2677,12 @@ export const setup = (
2353
2677
  mode.flingEnd(touchCount);
2354
2678
  mode.touchEnd(touchCount);
2355
2679
  }
2356
- }
2680
+ };
2357
2681
 
2358
2682
  const onFlingDrop = (data, customData, nexusCustomData) => {
2359
2683
  let touchCount = getTouchCount(nexusCustomData);
2360
2684
  visibleInfo.start = getVisibleStart(data);
2361
- }
2685
+ };
2362
2686
 
2363
2687
  const getTouchWall = () => {
2364
2688
  const boxSize = metroTemplate.getBoundingBoxSize();
@@ -2367,15 +2691,23 @@ export const setup = (
2367
2691
  top: 0,
2368
2692
  right: 0,
2369
2693
  bottom: 0,
2370
- }
2694
+ };
2371
2695
  if (vertical) {
2372
- wall.top = -boxSize.height + props.height - slideDivTop.value - (widgetRectInfo.padding.top + widgetRectInfo.padding.bottom);
2696
+ wall.top =
2697
+ -boxSize.height +
2698
+ props.height -
2699
+ slideDivTop.value -
2700
+ (widgetRectInfo.padding.top + widgetRectInfo.padding.bottom);
2373
2701
  wall.bottom = -slideDivTop.value;
2374
2702
  if (wall.top > wall.bottom) {
2375
2703
  wall.top = wall.bottom;
2376
2704
  }
2377
2705
  } else {
2378
- wall.left = -boxSize.width + props.width - slideDivLeft.value - (widgetRectInfo.padding.left + widgetRectInfo.padding.right);
2706
+ wall.left =
2707
+ -boxSize.width +
2708
+ props.width -
2709
+ slideDivLeft.value -
2710
+ (widgetRectInfo.padding.left + widgetRectInfo.padding.right);
2379
2711
  wall.right = -slideDivLeft.value;
2380
2712
  if (wall.left > wall.right) {
2381
2713
  wall.left = wall.right;
@@ -2383,10 +2715,12 @@ export const setup = (
2383
2715
  }
2384
2716
 
2385
2717
  return wall;
2386
- }
2718
+ };
2387
2719
 
2388
2720
  const updateRenderItems = (applyTmp, expand) => {
2389
- templateItemAdder.tryAddItemByPosition(visibleInfo.start + visibleInfo.range);
2721
+ templateItemAdder.tryAddItemByPosition(
2722
+ visibleInfo.start + visibleInfo.range
2723
+ );
2390
2724
  const updater = pageUpdater.update(
2391
2725
  metroTemplate,
2392
2726
  visibleInfo.startWithPadding - innerKeepTraceRange * pageRange,
@@ -2396,9 +2730,10 @@ export const setup = (
2396
2730
  permanentItemList
2397
2731
  );
2398
2732
  applyTmp ? updater.applyTmp() : updater.apply();
2399
- }
2733
+ };
2400
2734
 
2401
2735
  const updateTouchBoxCondition = () => {
2736
+ if (mode.getMode() != TOUCH_MODE) return;
2402
2737
  if (actorController != null) {
2403
2738
  const walls = getTouchWall();
2404
2739
 
@@ -2411,7 +2746,7 @@ export const setup = (
2411
2746
  .then([cmds.state().setHitWallOverflow()]), //TODO 通过prop设置哪个方向overflow
2412
2747
  ]);
2413
2748
  }
2414
- }
2749
+ };
2415
2750
 
2416
2751
  const touchRecorder = {
2417
2752
  moved: false,
@@ -2425,7 +2760,7 @@ export const setup = (
2425
2760
  },
2426
2761
  setTouchCount: function (count) {
2427
2762
  this.touchCount = count;
2428
- }
2763
+ },
2429
2764
  };
2430
2765
 
2431
2766
  const metroWidgetToken = metroWidgetTokenGen++;
@@ -2433,14 +2768,14 @@ export const setup = (
2433
2768
  let orderTouchSlideCallbacks;
2434
2769
  const SliderEditFuncReOrderWrap = (callback, addHeader = false) => {
2435
2770
  return (...args) => {
2436
- let pkg = { cb: callback, a: args }
2771
+ let pkg = { cb: callback, a: args };
2437
2772
  if (addHeader) {
2438
2773
  orderTouchSlideCallbacks.splice(0, 0, pkg);
2439
2774
  } else {
2440
2775
  orderTouchSlideCallbacks.push(pkg);
2441
2776
  }
2442
- }
2443
- }
2777
+ };
2778
+ };
2444
2779
 
2445
2780
  //TODO debug
2446
2781
  // let debugAnimId = -1;
@@ -2468,7 +2803,7 @@ export const setup = (
2468
2803
  // 执行结束后进行清理
2469
2804
  orderTouchSlideCallbacks.length = 0;
2470
2805
  }
2471
- )
2806
+ );
2472
2807
 
2473
2808
  // debugAnimId = actorController.debugGetAnimId();
2474
2809
  // debugViewId = divView.ViewId;
@@ -2517,19 +2852,26 @@ export const setup = (
2517
2852
  if (props.onScroll) {
2518
2853
  setOnMovement(DEFAULT_SENSITIVITY);
2519
2854
  }
2520
- }
2855
+ };
2521
2856
 
2522
2857
  function cleanTouch() {
2523
2858
  actorController.run((cmds) => [
2524
2859
  cmds.state().clearAllConditions(),
2525
- cmds.state().touchLockSwitch(false, vertical ? 1 : 2)
2526
- ])
2860
+ cmds.state().touchLockSwitch(false, vertical ? 1 : 2),
2861
+ ]);
2527
2862
  }
2528
2863
 
2529
2864
  //init
2530
2865
 
2531
2866
  function safeProvideData() {
2532
- return props.provideData() ?? [];
2867
+ const d = props.provideData();
2868
+ if (d instanceof Array) {
2869
+ return d;
2870
+ }
2871
+ console.warn(
2872
+ `MetroWidget provideData must return an array. name:${props.name} provideData:${d}`
2873
+ );
2874
+ return [];
2533
2875
  }
2534
2876
  pageUpdater = new PageUpdater(_updatePage, props.name);
2535
2877
  visibleInfo.range = vertical
@@ -2544,7 +2886,7 @@ export const setup = (
2544
2886
  } else if (props.data) {
2545
2887
  dataList = toRaw(props.data ?? [])?.concat();
2546
2888
  }
2547
- dataKeyList = dataList.map(i => i[DATA_ID_KEY]);
2889
+ dataKeyList = dataList.map((i) => i[DATA_ID_KEY]);
2548
2890
 
2549
2891
  templateItemAdder = new TemplateItemAdder(
2550
2892
  metroTemplate,
@@ -2569,8 +2911,16 @@ export const setup = (
2569
2911
  const item = getItemById(props.initFocusId);
2570
2912
  if (item) {
2571
2913
  init_focus_id = props.initFocusId;
2572
- if (item.itemConfig.itemSlide == METRO_WIDGET_CONST.ITEM_SLIDE.ACT_ITEM_FOCUS) {
2573
- initVisibleStart = _calculateVisibleStart(item.templateInfo, 0, item.templateInfo, visibleInfo);
2914
+ if (
2915
+ item.itemConfig.itemSlide ==
2916
+ METRO_WIDGET_CONST.ITEM_SLIDE.ACT_ITEM_FOCUS
2917
+ ) {
2918
+ initVisibleStart = _calculateVisibleStart(
2919
+ item.templateInfo,
2920
+ 0,
2921
+ item.templateInfo,
2922
+ visibleInfo
2923
+ );
2574
2924
  }
2575
2925
  }
2576
2926
  }
@@ -2624,7 +2974,7 @@ export const setup = (
2624
2974
  }
2625
2975
  });
2626
2976
 
2627
- onUpdated(() => { });
2977
+ onUpdated(() => {});
2628
2978
 
2629
2979
  onBeforeUnmount(() => {
2630
2980
  taskManager.cancelAllTask();
@@ -2649,6 +2999,6 @@ export const setup = (
2649
2999
  onTouchRelease: exportOnTouchRelease,
2650
3000
  currentFocusIndex,
2651
3001
  modeForExport,
2652
- onDispatchKeyDown
2653
- }
2654
- }
3002
+ onDispatchKeyDown,
3003
+ };
3004
+ };