@shijiu/jsview-vue 0.9.684 → 0.9.766

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 (113) hide show
  1. package/dom/bin/jsview-browser-debug-dom.min.js +1 -1
  2. package/dom/bin/jsview-dom.min.js +1 -1
  3. package/dom/bin/jsview-engine-js-browser.min.js +1 -1
  4. package/dom/bin/jsview-forge-define.min.js +1 -1
  5. package/dom/jsv-engine-js-browser.js +6 -0
  6. package/dom/target_core_revision.js +4 -4
  7. package/loader/loader.js +4 -0
  8. package/package.json +1 -1
  9. package/patches/node_modules/@vue/cli-service/lib/config/base.js +1 -1
  10. package/samples/AnimPicture/App.vue +5 -5
  11. package/samples/Basic/components/div/DivLayout.vue +1 -1
  12. package/samples/Basic/components/img/ImageGroup.vue +2 -2
  13. package/samples/Basic/components/img/ImgLayout.vue +79 -15
  14. package/samples/Basic/components/text/TextDirection.vue +104 -0
  15. package/samples/Basic/components/text/TextEmoji.vue +1 -1
  16. package/samples/Basic/components/text/TextGroup1.vue +1 -1
  17. package/samples/Basic/components/text/TextGroup2.vue +11 -1
  18. package/samples/BasicFocusControl/components/BaseBlock.vue +2 -2
  19. package/samples/Collision/App.vue +11 -11
  20. package/samples/DemoHomepage/App.vue +43 -8
  21. package/samples/DemoHomepage/router.js +13 -10
  22. package/samples/DemoHomepage/views/Homepage.vue +83 -96
  23. package/samples/FilterDemo/App.vue +1 -1
  24. package/samples/FlipCard/App.vue +2 -2
  25. package/samples/FlipCard/FlipCard.vue +3 -3
  26. package/samples/GridDemo/App.vue +3 -3
  27. package/samples/GridDemo/ButtonBlock.vue +2 -2
  28. package/samples/GridDemo/FocusItem.vue +2 -2
  29. package/samples/GridDemo/Item.vue +1 -1
  30. package/samples/HashHistory/App.vue +10 -3
  31. package/samples/HashHistory/components/Item.vue +1 -1
  32. package/samples/ImpactStop/App.vue +15 -11
  33. package/samples/Input/InputPanel.vue +1 -1
  34. package/samples/LongImage/Button.vue +1 -1
  35. package/samples/LongImage/ButtonItem.vue +1 -1
  36. package/samples/LongImage/LongImageScroll.vue +2 -2
  37. package/samples/LongText/App.vue +1 -1
  38. package/samples/LongText/Button.vue +1 -1
  39. package/samples/LongText/ButtonItem.vue +1 -1
  40. package/samples/LongText/LongTextScroll.vue +3 -3
  41. package/samples/Marquee/longText.js +2 -2
  42. package/samples/MetroWidgetDemos/Advanced/ButtonItem.vue +4 -4
  43. package/samples/MetroWidgetDemos/Advanced/widgets/Item.vue +3 -4
  44. package/samples/MetroWidgetDemos/Advanced/widgets/WidgetItem.vue +2 -3
  45. package/samples/MetroWidgetDemos/Advanced/widgets/Widgets.vue +1 -1
  46. package/samples/MetroWidgetDemos/Item.vue +3 -19
  47. package/samples/MetroWidgetDemos/PerformanceTest/App.vue +4 -4
  48. package/samples/MetroWidgetDemos/PerformanceTest/components/ContentItem.vue +1 -1
  49. package/samples/MetroWidgetDemos/PerformanceTest/components/MyTab.vue +3 -3
  50. package/samples/MetroWidgetDemos/PingPong/AppPage.vue +2 -2
  51. package/samples/MetroWidgetDemos/PingPong/TabItem.vue +1 -1
  52. package/samples/MetroWidgetDemos/PingPong/ViewSwiper.vue +3 -3
  53. package/samples/MetroWidgetDemos/Simple/RelativeTemplate.vue +2 -2
  54. package/samples/MetroWidgetDemos/WidgetItem.vue +2 -3
  55. package/samples/NinePatchDemo/App.vue +2 -2
  56. package/samples/NinePatchDemo/Item.vue +2 -2
  57. package/samples/Preload/App.vue +1 -1
  58. package/samples/Preload/Item.vue +1 -1
  59. package/samples/QrcodeDemo/App.vue +1 -1
  60. package/samples/SoundPool/App.vue +3 -3
  61. package/samples/SpriteImage/App.vue +5 -0
  62. package/samples/TextBox/App.vue +2 -1
  63. package/samples/TextureAnimation/App2.vue +1 -1
  64. package/samples/ThrowMoveDemo/LRParabolicDemo.vue +33 -47
  65. package/samples/TouchSample/MetroWidgetHorizontal.vue +1 -1
  66. package/samples/TouchSample/MetroWidgetVertical.vue +1 -1
  67. package/samples/TransitPage/App.vue +1 -1
  68. package/samples/VideoDemo/App.vue +8 -8
  69. package/samples/VideoDemo/components/Button.vue +1 -1
  70. package/samples/VideoDemo/components/Controllor.vue +1 -1
  71. package/samples/VisibleSensorDemo/App.vue +3 -3
  72. package/scripts/jsview-run-android.js +5 -4
  73. package/utils/JsViewEngineWidget/JsvFocusBlock.vue +4 -4
  74. package/utils/JsViewEngineWidget/MetroWidget/MetroWidget.vue +65 -39
  75. package/utils/JsViewEngineWidget/TemplateParser.js +138 -146
  76. package/utils/JsViewEngineWidget/WidgetCommon.js +12 -3
  77. package/utils/JsViewPlugin/BrowserPluginLoader.js +4 -2
  78. package/utils/JsViewPlugin/JsvAudio/AudioProxy.js +302 -0
  79. package/utils/JsViewPlugin/JsvAudio/CheckType.js +68 -0
  80. package/utils/JsViewPlugin/JsvAudio/Events.js +17 -0
  81. package/utils/JsViewPlugin/JsvAudio/JsvAudio.vue +176 -0
  82. package/utils/JsViewPlugin/JsvAudio/JsvAudioBridgeProxy.js +40 -0
  83. package/utils/JsViewPlugin/JsvAudio/JsvAudioBrowser.vue +46 -0
  84. package/utils/JsViewPlugin/JsvAudio/PluginLoader.js +140 -0
  85. package/utils/JsViewPlugin/JsvAudio/index.js +26 -0
  86. package/utils/JsViewPlugin/JsvAudio/version.js +24 -0
  87. package/utils/JsViewPlugin/JsvPlayer/index.js +1 -1
  88. package/utils/JsViewPlugin/JsvPlayer/version.js +5 -5
  89. package/utils/JsViewVueTools/JsvHashHistory.js +34 -8
  90. package/utils/JsViewVueTools/JsvImpactTracer.js +2 -2
  91. package/utils/JsViewVueTools/JsvRuntimeBridge.js +46 -8
  92. package/utils/JsViewVueTools/JsvStyleClass.js +9 -0
  93. package/utils/{JsViewVueWidget/utils/text.js → JsViewVueTools/JsvTextTools.js} +3 -4
  94. package/utils/JsViewVueTools/TypeCheckAndSet.js +3 -3
  95. package/utils/JsViewVueTools/index.js +2 -1
  96. package/utils/JsViewVueWidget/BrowserDebugWidget/BrowserTextureAnim.vue +5 -7
  97. package/utils/JsViewVueWidget/JsvActorMove/JsvActorMove.vue +20 -22
  98. package/utils/JsViewVueWidget/JsvApic/JsvApic.vue +4 -4
  99. package/utils/JsViewVueWidget/JsvGrid.vue +1 -9
  100. package/utils/JsViewVueWidget/JsvInput/Cursor.vue +1 -1
  101. package/utils/JsViewVueWidget/JsvMarquee.vue +22 -12
  102. package/utils/JsViewVueWidget/JsvMaskClipDiv.vue +1 -1
  103. package/utils/JsViewVueWidget/JsvNinePatch.vue +63 -53
  104. package/utils/JsViewVueWidget/JsvSpray/JsvSpray.vue +10 -5
  105. package/utils/JsViewVueWidget/JsvSpriteAnim/JsvSpriteAnim.vue +2 -2
  106. package/utils/JsViewVueWidget/JsvSwiper/JsvSwiper.vue +3 -3
  107. package/utils/JsViewVueWidget/JsvSwiper3D/JsvSwiper.vue +1 -1
  108. package/utils/JsViewVueWidget/JsvTextBox.vue +11 -31
  109. package/utils/JsViewVueWidget/JsvTouchContainer.vue +2 -2
  110. package/utils/JsViewVueWidget/JsvTransparentDiv.vue +1 -1
  111. package/utils/JsViewVueWidget/JsvVisibleSensor/JsvVisibleSensor.vue +5 -5
  112. package/utils/JsViewVueWidget/index.js +8 -8
  113. package/utils/JsViewVueWidget/utils/index.js +0 -8
@@ -2,7 +2,7 @@
2
2
  * @Author: ChenChanghua
3
3
  * @Date: 2021-09-22 16:08:58
4
4
  * @LastEditors: ChenChanghua
5
- * @LastEditTime: 2022-11-07 15:51:14
5
+ * @LastEditTime: 2022-12-19 11:17:10
6
6
  * @Description: file content
7
7
  -->
8
8
 
@@ -23,7 +23,13 @@
23
23
  * name {string} 用于设置焦点的名称
24
24
  * padding {object} 控件内边距, 默认为{left: 0, right: 0, top: 0, bottom: 0}
25
25
  * direction {enum} (必选)控件方向 HORIZONTAL/VERTICAL
26
- * loopFocus {boolean} 焦点到边界后自动转到下一行,默认false
26
+ * focusMoveType {int} 焦点移动的模式, 可通过 | 运算进行组合
27
+ NO_ADJUST: 无特殊处理
28
+ COLUMN_LOOP: 到达列首/尾后跳转到上/下一列, 只在水平滚动时生效
29
+ ROW_LOOP: 到达行首/尾后跳转到上/下一行, 只在竖直滚动时生效
30
+ COLUMN_FIND_NEAR: 一列中没有下一个元素时是否跳转到相邻列
31
+ ROW_FIND_NEAR: 一行中没有下一个元素时是否跳转到相邻行
32
+
27
33
  * initFocusId {int} 初始焦点,默认为0
28
34
  * slideSetting {SlideSetting} 页面滑动的设置, 目前SlideSetting有三个子类, 具体见 WidgetCommon 中的说明
29
35
  WholePageSlide
@@ -80,6 +86,7 @@
80
86
  * loadAll {boolean} 加载不显示的view,触控场景使用
81
87
  * flingPageWidth {}
82
88
  * flingPageEdge {}
89
+ * disableClip {boolean} 取消显示范围的clipView
83
90
  * methods:
84
91
  getFocusBlockRef 获取此MetroWidget的 jsv-focus-block句柄,可以使用requestFocus完成获焦
85
92
 
@@ -397,6 +404,14 @@ const props = defineProps({
397
404
  onScroll: {
398
405
  type: Function,
399
406
  },
407
+ focusMoveType: {
408
+ type: Number,
409
+ default: 0,
410
+ },
411
+ disableClip: {
412
+ type: Boolean,
413
+ default: false,
414
+ },
400
415
  });
401
416
 
402
417
  let dataUpdateToken = ref(0);
@@ -423,7 +438,7 @@ let itemRender = ref(!props.enableItemRenderBreak);
423
438
  let permanentItemList = [];
424
439
  let preUpdateVisibleStart = 0;
425
440
  let mounted = false;
426
- let focusNode = ref(null);
441
+ let focusNode = shallowRef(null);
427
442
  let pageRange = vertical ? props.height : props.width;
428
443
 
429
444
  let slideLock = false;
@@ -464,8 +479,8 @@ let visibleInfo = {
464
479
  },
465
480
  };
466
481
 
467
- let locateDiv = ref(null);
468
- let slideDiv = ref(null);
482
+ let locateDiv = shallowRef(null);
483
+ let slideDiv = shallowRef(null);
469
484
  let renderData = shallowRef([]);
470
485
  let slideDivLeft = ref(0);
471
486
  let slideDivTop = ref(0);
@@ -483,7 +498,7 @@ const _onFocusChange = (id) => {
483
498
  const _getCurrentId = () => {
484
499
  return {
485
500
  id: focusId,
486
- index: templateParser.FocusIdToIndex(focusId),
501
+ index: templateParser.IdToIndex(focusId),
487
502
  };
488
503
  };
489
504
 
@@ -563,7 +578,7 @@ const setFocusId = (id, needSlide = true, doAnim = false, extraSetting) => {
563
578
  let next_focus_item = templateParser.GetItemById(id);
564
579
  if (next_focus_item) {
565
580
  if (needSlide) {
566
- slideToItem(templateParser.FocusIdToIndex(id), doAnim);
581
+ slideToItem(templateParser.IdToIndex(id), doAnim);
567
582
  }
568
583
  let unlock = null;
569
584
  if (extraSetting) {
@@ -589,8 +604,8 @@ const setFocusId = (id, needSlide = true, doAnim = false, extraSetting) => {
589
604
  };
590
605
  _updateBlurItem();
591
606
  _updateFocusItem();
592
- onItemBlur(templateParser.FocusIdToIndex(preFocusId));
593
- onItemFocus(templateParser.FocusIdToIndex(focusId), preEdgeRect);
607
+ onItemBlur(templateParser.IdToIndex(preFocusId));
608
+ onItemFocus(templateParser.IdToIndex(focusId), preEdgeRect);
594
609
  unlock?.();
595
610
  }
596
611
  };
@@ -797,7 +812,7 @@ const refreshData = (force_update) => {
797
812
  dataUpdateToken.value++;
798
813
  pageUpdater.apply();
799
814
  _updateFocusItem();
800
- onItemFocus(templateParser.FocusIdToIndex(focusId), null);
815
+ onItemFocus(templateParser.IdToIndex(focusId), null);
801
816
  if (needSlide) {
802
817
  _slideTo(visibleInfo.start, null);
803
818
  } else if (need_update_content) {
@@ -1053,7 +1068,7 @@ const onKeyDown = (ev) => {
1053
1068
  _moveToNext(horizontal_direction, vertical_direction);
1054
1069
  break;
1055
1070
  case 13:
1056
- onItemClick(templateParser.FocusIdToIndex(focusId));
1071
+ onItemClick(templateParser.IdToIndex(focusId));
1057
1072
  break;
1058
1073
  default:
1059
1074
  //只接受上下左右确定键
@@ -1093,7 +1108,7 @@ const _onTemplateAdd = (item) => {
1093
1108
  this.slotMounted.value = true;
1094
1109
  if (callFocusAfterUpdate && this.data.id === focusId) {
1095
1110
  nextTick(() => {
1096
- onItemFocus(templateParser.FocusIdToIndex(focusId), preEdgeRect);
1111
+ onItemFocus(templateParser.IdToIndex(focusId), preEdgeRect);
1097
1112
  });
1098
1113
  callFocusAfterUpdate = false;
1099
1114
  }
@@ -1198,7 +1213,9 @@ const _onCustomerEvent = (ev) => {
1198
1213
  yPos: item_layout.top,
1199
1214
  width: item_layout.width,
1200
1215
  height: item_layout.height,
1201
- index: templateParser.FocusIdToIndex(focusId),
1216
+ centerYPos: Math.floor(item_layout.top + item_layout.height / 2),
1217
+ centerXPos: Math.floor(item_layout.left + item_layout.width / 2),
1218
+ index: templateParser.IdToIndex(focusId),
1202
1219
  };
1203
1220
 
1204
1221
  let cur_slide = _calculateVisibleStart(obj, direction);
@@ -1244,15 +1261,14 @@ const _moveToNext = (
1244
1261
  item_edge_rect
1245
1262
  ) => {
1246
1263
  let cur_focus_item = templateParser.GetItemById(focusId);
1247
- let next_item_id = templateParser.GetNextItem(
1264
+ let next_focus_item = templateParser.GetNextItem(
1248
1265
  focusId,
1249
1266
  vertical_direction,
1250
1267
  horizontal_direction,
1251
- props.loopFocus
1268
+ props.focusMoveType
1252
1269
  );
1253
- if (next_item_id >= 0) {
1270
+ if (next_focus_item !== null) {
1254
1271
  preFocusId = focusId;
1255
- let next_focus_item = templateParser.GetItemById(next_item_id);
1256
1272
  templateItemAdder.tryAddItem(next_focus_item, 1);
1257
1273
  focusId = next_focus_item.id;
1258
1274
 
@@ -1261,8 +1277,7 @@ const _moveToNext = (
1261
1277
 
1262
1278
  let cur_visible_start = _calculateVisibleStart(next_focus_item, direction);
1263
1279
  if (
1264
- !innerData[templateParser.FocusIdToIndex(next_item_id)].itemConfig
1265
- ?.takeOverSlide &&
1280
+ !innerData[templateParser.IdToIndex(focusId)].itemConfig?.takeOverSlide &&
1266
1281
  visibleInfo.start !== cur_visible_start
1267
1282
  ) {
1268
1283
  if (next_focus_item.doSlide) {
@@ -1284,7 +1299,7 @@ const _moveToNext = (
1284
1299
  1,
1285
1300
  visibleInfo.endWithPadding + props.keepTraceRange * pageRange
1286
1301
  ),
1287
- next_item_id,
1302
+ next_focus_item.id,
1288
1303
  false,
1289
1304
  permanentItemList
1290
1305
  );
@@ -1294,7 +1309,7 @@ const _moveToNext = (
1294
1309
  templateParser,
1295
1310
  cur_visible_start,
1296
1311
  cur_visible_start + visibleInfo.range + visibleInfo.padding.end - 1,
1297
- next_item_id,
1312
+ next_focus_item.id,
1298
1313
  false,
1299
1314
  permanentItemList
1300
1315
  );
@@ -1333,8 +1348,8 @@ const _moveToNext = (
1333
1348
  preEdgeRect = rect;
1334
1349
  _updateBlurItem();
1335
1350
  _updateFocusItem();
1336
- onItemBlur(templateParser.FocusIdToIndex(preFocusId));
1337
- onItemFocus(templateParser.FocusIdToIndex(focusId), preEdgeRect);
1351
+ onItemBlur(templateParser.IdToIndex(preFocusId));
1352
+ onItemFocus(templateParser.IdToIndex(focusId), preEdgeRect);
1338
1353
  } else {
1339
1354
  let x_off_set = props.direction === VERTICAL ? 0 : visibleInfo.start;
1340
1355
  let y_off_set = props.direction === VERTICAL ? visibleInfo.start : 0;
@@ -1358,7 +1373,7 @@ const _moveToNext = (
1358
1373
  height: cur_focus_item.height,
1359
1374
  };
1360
1375
  props.onEdge?.({ direction: edge, rect: rect });
1361
- innerData[templateParser.FocusIdToIndex(focusId)].callbacks.onWidgetEdge?.({
1376
+ innerData[templateParser.IdToIndex(focusId)].callbacks.onWidgetEdge?.({
1362
1377
  direction: edge,
1363
1378
  });
1364
1379
  }
@@ -1384,9 +1399,17 @@ const _calculateVisibleStart = (target_item, direction) => {
1384
1399
  );
1385
1400
  break;
1386
1401
  case SlideSetting.Type.WHOLE_PAGE:
1387
- new_visible_start = templateParser.GetItem(target_item.pageHeadIndex)[
1388
- pos_key
1389
- ];
1402
+ if (typeof target_item.pageHeadIndex == "undefined") {
1403
+ //TODO 子控制滚动时whole page滚动
1404
+ console.error(
1405
+ "child controlled whole page slide type is not supported."
1406
+ );
1407
+ } else {
1408
+ new_visible_start = templateParser.GetItem(target_item.pageHeadIndex)[
1409
+ pos_key
1410
+ ];
1411
+ }
1412
+
1390
1413
  break;
1391
1414
  case SlideSetting.Type.SEAMLESS:
1392
1415
  if (
@@ -1533,7 +1556,7 @@ const _onFocus = (params) => {
1533
1556
  enterFocusId = -1;
1534
1557
  enterFocusRect = null;
1535
1558
  _updateFocusItem();
1536
- onItemFocus(templateParser.FocusIdToIndex(focusId), preEdgeRect);
1559
+ onItemFocus(templateParser.IdToIndex(focusId), preEdgeRect);
1537
1560
  props.onFocus?.();
1538
1561
  };
1539
1562
 
@@ -1547,7 +1570,7 @@ const _onBlur = () => {
1547
1570
  }
1548
1571
  preFocusId = focusId;
1549
1572
  _updateBlurItem();
1550
- innerData[templateParser.FocusIdToIndex(preFocusId)].callbacks.onBlur();
1573
+ innerData[templateParser.IdToIndex(preFocusId)].callbacks.onBlur();
1551
1574
 
1552
1575
  props.onBlur?.();
1553
1576
  };
@@ -1560,11 +1583,11 @@ const _onSlideEnd = (event) => {
1560
1583
  };
1561
1584
 
1562
1585
  const _updateFocusItem = () => {
1563
- _setZIndex(templateParser.FocusIdToIndex(focusId), innerData.length, true);
1586
+ _setZIndex(templateParser.IdToIndex(focusId), innerData.length, true);
1564
1587
  };
1565
1588
 
1566
1589
  const _updateBlurItem = () => {
1567
- _setZIndex(templateParser.FocusIdToIndex(preFocusId), 0, false);
1590
+ _setZIndex(templateParser.IdToIndex(preFocusId), 0, false);
1568
1591
  };
1569
1592
 
1570
1593
  const _updateFocusByDragInfo = (viewX, viewY) => {
@@ -1712,8 +1735,8 @@ const _onScroll = () => {
1712
1735
  const _updatePosition = (x, y, anim_info) => {
1713
1736
  if (slideLock) return;
1714
1737
  if (toRaw(slideDiv.value)) {
1715
- let pre_left = toRaw(slideDiv.value).style.left,
1716
- pre_top = toRaw(slideDiv.value).style.top;
1738
+ let pre_left = slideDivLeft.value,
1739
+ pre_top = slideDivTop.value;
1717
1740
  //jsvMaskView的位置更新时会被设置位0,因此不能通过ResetLayoutParams设置位置
1718
1741
  slideDivLeft.value = x;
1719
1742
  slideDivTop.value = y;
@@ -1734,7 +1757,9 @@ const _updatePosition = (x, y, anim_info) => {
1734
1757
  slide_animation.SetAnimationListener(
1735
1758
  new Forge.AnimationListener(anim_info.onstart, anim_info.onend, null)
1736
1759
  );
1737
- toRaw(slideDiv.value).jsvMaskView.StartAnimation(slide_animation);
1760
+ toRaw(slideDiv.value)
1761
+ .jsvGetProxyView(true)
1762
+ .StartAnimation(slide_animation);
1738
1763
  }
1739
1764
  _onScroll();
1740
1765
  }
@@ -1742,7 +1767,7 @@ const _updatePosition = (x, y, anim_info) => {
1742
1767
 
1743
1768
  const _initRootTouch = () => {
1744
1769
  if (props.enableTouch && toRaw(slideDiv.value)) {
1745
- let view = toRaw(slideDiv.value).jsvMaskView;
1770
+ let view = toRaw(slideDiv.value).jsvGetProxyView(true);
1746
1771
  var drag_setting = new Forge.DragSetting(
1747
1772
  dragDirection,
1748
1773
  20,
@@ -1759,7 +1784,7 @@ const _initItemViewTouch = (itemDivRef, index) => {
1759
1784
  if (props.enableTouch) {
1760
1785
  if (itemDivRef) {
1761
1786
  // 为view添加触控处理
1762
- let view = itemDivRef.jsvMaskView;
1787
+ let view = itemDivRef.jsvGetProxyView(true);
1763
1788
  let dragSetting = new Forge.DragSetting(
1764
1789
  Forge.DragSetting.DIRECTION_DISABLE,
1765
1790
  20,
@@ -1808,6 +1833,7 @@ templateParser = _getTemplateParser(
1808
1833
  props.supportHistoryPath,
1809
1834
  props.layoutType
1810
1835
  );
1836
+
1811
1837
  templateItemAdder = new TemplateItemAdder(
1812
1838
  templateParser,
1813
1839
  dataList,
@@ -1846,7 +1872,7 @@ slidePile = new Forge.RectArea(
1846
1872
  let init_focus_id = 0;
1847
1873
  let cur_visible_start = 0;
1848
1874
 
1849
- if (typeof props.initFocusId == 'number') {
1875
+ if (typeof props.initFocusId == "number") {
1850
1876
  templateItemAdder.tryAddItemById(props.initFocusId);
1851
1877
  const item = templateParser.GetItemById(props.initFocusId);
1852
1878
  if (item) {
@@ -1884,7 +1910,7 @@ onMounted(() => {
1884
1910
  _slideTo(visibleInfo.start, null);
1885
1911
  }
1886
1912
 
1887
- onItemFocus(templateParser.FocusIdToIndex(focusId), preEdgeRect);
1913
+ onItemFocus(templateParser.IdToIndex(focusId), preEdgeRect);
1888
1914
 
1889
1915
  if (props.enableItemRenderBreak) {
1890
1916
  nextTick(() => {
@@ -1918,7 +1944,7 @@ defineExpose(exportObject);
1918
1944
  top: top,
1919
1945
  width: width,
1920
1946
  height: height,
1921
- overflow: 'hidden',
1947
+ overflow: disableClip ? null : 'hidden',
1922
1948
  }"
1923
1949
  >
1924
1950
  <div :style="{ left: innerPadding.left, top: innerPadding.top }">
@@ -1,7 +1,7 @@
1
1
  /* eslint-disable */
2
2
  import { RangesModel, SingleRangeModel } from "./RangeModel";
3
3
  import { RectArea } from "./RectUtils";
4
- import { VERTICAL, HORIZONTAL } from "./WidgetCommon";
4
+ import { VERTICAL, HORIZONTAL, FocusMoveType } from "./WidgetCommon";
5
5
  const TAG = "TemplateParser: ";
6
6
 
7
7
  function integerCheck(value, warn_func) {
@@ -1064,7 +1064,7 @@ class TemplateParser {
1064
1064
  return this._Template.List.length;
1065
1065
  }
1066
1066
 
1067
- FocusIdToIndex(id) {
1067
+ IdToIndex(id) {
1068
1068
  return this._Template.IdsMap[id];
1069
1069
  }
1070
1070
 
@@ -1200,64 +1200,6 @@ class TemplateParser {
1200
1200
  this._FindFocusableNeighbor("right", item);
1201
1201
  }
1202
1202
  }
1203
- // if (this._Template.Orient.type !== VERTICAL) {
1204
- // // 从后向前找(最后一项不用检查)
1205
- // // 如果向下未找到对象,则查找最后一行的最后一项
1206
- // let last_down_idx = null;
1207
- // let min_distance = -1;
1208
- // let distance = 0;
1209
- // // 向下操作 只检查最后一项
1210
- // for (let k = last_item_index - 1; k >= 0; k--) {
1211
- // const pre_col_item = template_list[k];
1212
- // if (pre_col_item.focusable) {
1213
- // if (pre_col_item.yPos >= last_item.yPos + last_item.height) {
1214
- // if (
1215
- // pre_col_item.neighborIndexList.right.length === 0 ||
1216
- // !this._CheckIdsHasFocusable(
1217
- // pre_col_item.neighborIndexList.right
1218
- // ) ||
1219
- // this._IsInNeighborList(
1220
- // pre_col_item.neighborIndexList.right,
1221
- // last_item_index
1222
- // )
1223
- // ) {
1224
- // // 有邻居中有last_item_index
1225
- // distance =
1226
- // (last_item.xPos - pre_col_item.xPos) ** 2 +
1227
- // (last_item.yPos - pre_col_item.yPos) ** 2;
1228
- // if (min_distance === -1) {
1229
- // min_distance = distance;
1230
- // last_down_idx = k;
1231
- // } else if (min_distance > distance) {
1232
- // min_distance = distance;
1233
- // last_down_idx = k;
1234
- // }
1235
- // }
1236
- // }
1237
- // }
1238
- // }
1239
- // if (last_down_idx) {
1240
- // last_item.neighborIndexList.bottom = []; // 清除无效项
1241
- // console.log('cchtest bottom add 2', last_down_idx)
1242
- // last_item.neighborIndexList.bottom.push(last_down_idx);
1243
- // }
1244
- // } else {
1245
- // // vertical
1246
- // for (let k = last_item_index - 1; k >= 0; k--) {
1247
- // const pre_row_item = template_list[k];
1248
- // if (pre_row_item.focusable) {
1249
- // if (
1250
- // pre_row_item.yPos + pre_row_item.height <
1251
- // last_item.yPos + last_item.height
1252
- // ) {
1253
- // if (pre_row_item.neighborIndexList.bottom.length === 0) {
1254
- // console.log('cchtest bottom add 3', last_item_index)
1255
- // pre_row_item.neighborIndexList.bottom.push(last_item_index);
1256
- // }
1257
- // }
1258
- // }
1259
- // }
1260
- // }
1261
1203
  }
1262
1204
 
1263
1205
  /**
@@ -1270,47 +1212,76 @@ class TemplateParser {
1270
1212
  * @param {int} base_item_id Item的Id
1271
1213
  * @param {int} vertical_offset 纵向偏移(-1为向上,1为向下)
1272
1214
  * @param {int} horizontal_offset 横向偏移(-1为向左,1为向右)
1273
- * @param {bool} need_loop 循环查找
1215
+ * @param {int} focus_move_type 焦点移动设置
1274
1216
  * @return {int} 下一个Item的Id,-1为该方向未找到Item(到达边缘)
1275
1217
  * */
1276
- GetNextItem(base_item_id, vertical_offset, horizontal_offset, need_loop) {
1218
+ GetNextItem(
1219
+ base_item_id,
1220
+ vertical_offset,
1221
+ horizontal_offset,
1222
+ focus_move_type
1223
+ ) {
1277
1224
  if (vertical_offset === 0 && horizontal_offset === 0)
1278
1225
  console.log("GetNextItem(): offset is 0");
1279
1226
  // Forge.ThrowError("GetNextItem(): offset is 0");
1280
1227
 
1281
1228
  if (vertical_offset !== 0 && horizontal_offset !== 0) {
1282
1229
  console.log(
1283
- "GetNextItem(): not support change vertical and horizontal and the same time"
1230
+ "GetNextItem(): not support change vertical and horizontal at the same time"
1284
1231
  );
1285
1232
  // Forge.ThrowError("GetNextItem(): not support change vertical and horizontal and the same time");
1286
1233
  }
1287
1234
 
1288
- const list_index = this._Template.IdsMap[base_item_id];
1235
+ const item_index = this.IdToIndex(base_item_id);
1289
1236
  const offset = vertical_offset !== 0 ? vertical_offset : horizontal_offset;
1290
1237
  let next_template_item = this._GetNextItem(
1291
- list_index,
1238
+ item_index,
1292
1239
  offset,
1293
1240
  vertical_offset !== 0
1294
1241
  );
1242
+ const is_vertical = this._Template.Orient.type === VERTICAL;
1295
1243
 
1296
- if (need_loop && next_template_item === null) {
1297
- if (vertical_offset !== 0) {
1298
- next_template_item = this._GetNextLoopItemVertical(
1299
- list_index,
1300
- vertical_offset
1244
+ if (next_template_item === null) {
1245
+ // 在次方向的焦点移动才会loop
1246
+ if (
1247
+ is_vertical &&
1248
+ focus_move_type & FocusMoveType.ROW_LOOP &&
1249
+ horizontal_offset != 0
1250
+ ) {
1251
+ next_template_item = this._GetNextLoopItem(
1252
+ item_index,
1253
+ horizontal_offset,
1254
+ is_vertical
1301
1255
  );
1302
- } else {
1303
- next_template_item = this._GetNextLoopItemHorizontal(
1304
- list_index,
1305
- horizontal_offset
1256
+ } else if (
1257
+ !is_vertical &&
1258
+ focus_move_type & FocusMoveType.COLUMN_LOOP &&
1259
+ vertical_offset != 0
1260
+ ) {
1261
+ next_template_item = this._GetNextLoopItem(
1262
+ item_index,
1263
+ vertical_offset,
1264
+ is_vertical
1306
1265
  );
1307
1266
  }
1308
1267
  }
1309
1268
 
1310
1269
  if (next_template_item === null) {
1311
- return -1;
1270
+ // 临近行的焦点移动
1271
+ if (
1272
+ vertical_offset != 0 &&
1273
+ focus_move_type & FocusMoveType.ROW_FIND_NEAR
1274
+ ) {
1275
+ next_template_item = this._GetNearLineItem(item_index, vertical_offset, true);
1276
+ } else if (
1277
+ horizontal_offset != 0 &&
1278
+ focus_move_type & FocusMoveType.COLUMN_FIND_NEAR
1279
+ ) {
1280
+ next_template_item = this._GetNearLineItem(item_index, horizontal_offset, false);
1281
+ }
1312
1282
  }
1313
- return next_template_item.id;
1283
+
1284
+ return next_template_item;
1314
1285
  }
1315
1286
 
1316
1287
  _GetNextItem(index, offset, vertical) {
@@ -1476,94 +1447,115 @@ class TemplateParser {
1476
1447
  return null;
1477
1448
  }
1478
1449
 
1479
- _GetNextLoopItemVertical(index, offset) {
1480
- const template_list = this._Template.List;
1481
- const base_item = template_list[index];
1482
- const center_x = base_item.centerXPos;
1483
- let direction = "bottom";
1484
- // Normalize offset
1485
- if (offset > 0) {
1486
- direction = "top";
1487
- }
1488
- let found = false;
1489
- let next_index = -1;
1450
+ _GetItemDistance(item1, item2) {
1451
+ return (
1452
+ Math.pow(item1.centerXPos - item2.centerXPos, 2) +
1453
+ Math.pow(item1.centerYPos - item2.centerYPos, 2)
1454
+ );
1455
+ }
1490
1456
 
1491
- // 获得邻近点列表
1492
- let neighbor_list = template_list[index].neighborIndexList[direction];
1493
- if (template_list[index].tmpNeighborIndexList[direction].length > 0) {
1494
- neighbor_list = neighbor_list.concat(
1495
- template_list[index].tmpNeighborIndexList[direction]
1496
- );
1457
+ _GetTotalNeighbor(index, direction) {
1458
+ const item = this._Template.List[index];
1459
+ return item.neighborIndexList[direction].concat(
1460
+ item.tmpNeighborIndexList[direction]
1461
+ );
1462
+ }
1463
+
1464
+ _GetNearestItem(target_item_index, item_index_list) {
1465
+ let nearest_index = -1,
1466
+ min_distance = Number.POSITIVE_INFINITY;
1467
+ let target_item = this._Template.List[target_item_index];
1468
+ for (let i of item_index_list) {
1469
+ const d = this._GetItemDistance(this._Template.List[i], target_item);
1470
+ if (d < min_distance) {
1471
+ nearest_index = i;
1472
+ min_distance = d;
1473
+ }
1497
1474
  }
1475
+ return nearest_index;
1476
+ }
1498
1477
 
1499
- while (neighbor_list.length >= 1) {
1500
- for (let i = 0; i < neighbor_list.length; i++) {
1501
- next_index = neighbor_list[i];
1502
- const checking_item = template_list[next_index];
1503
- if (
1504
- center_x <= checking_item.xPos + checking_item.width - 1 &&
1505
- center_x >= checking_item.xPos
1506
- ) {
1507
- neighbor_list =
1508
- template_list[next_index].neighborIndexList[direction];
1509
- found = true;
1478
+ _GetNextLoopItem(index, offset, is_vertical) {
1479
+ const template_list = this._Template.List;
1480
+ const base_item = template_list[index];
1481
+ let search_direction = is_vertical ? "right" : "bottom";
1482
+ let start_direction = is_vertical ? "top" : "left";
1483
+ if (offset > 0) {
1484
+ search_direction = is_vertical ? "left" : "top";
1485
+ start_direction = is_vertical ? "bottom" : "right";
1486
+ }
1487
+ let target_index = -1;
1488
+ let focusable_target = -1;
1489
+ let start_index = -1;
1490
+ let neighbor_list = [];
1491
+ //寻找下一列的起始item
1492
+ neighbor_list = this._GetTotalNeighbor(index, search_direction);
1493
+ while (start_index < 0 && neighbor_list.length > 0) {
1494
+ for (let i of neighbor_list) {
1495
+ if (this._GetTotalNeighbor(i, start_direction).length > 0) {
1496
+ start_index = i;
1510
1497
  break;
1498
+ } else {
1499
+ //TODO 是否要用递归
1500
+ neighbor_list = this._GetTotalNeighbor(i, search_direction);
1511
1501
  }
1512
1502
  }
1513
1503
  }
1504
+ if (start_index >= 0) {
1505
+ neighbor_list = this._GetTotalNeighbor(start_index, start_direction);
1506
+
1507
+ //寻找最近的neighbor
1508
+ let nearest_index = -1,
1509
+ min_distance = Number.POSITIVE_INFINITY;
1510
+ for (let i of neighbor_list) {
1511
+ const d = this._GetItemDistance(template_list[i], base_item);
1512
+ if (d < min_distance) {
1513
+ nearest_index = i;
1514
+ min_distance = d;
1515
+ }
1516
+ }
1514
1517
 
1515
- if (found) {
1516
- if (!template_list[next_index].focusable) {
1517
- // 如果是占位符,则查找占位符的下一个
1518
- return this._GetNextLoopItemVertical(next_index, offset);
1518
+ neighbor_list = this._GetTotalNeighbor(nearest_index, search_direction);
1519
+ while (neighbor_list.length > 0) {
1520
+ target_index = this._GetNearestItem(nearest_index, neighbor_list);
1521
+ if (template_list[target_index].focusable) {
1522
+ focusable_target = target_index;
1523
+ }
1524
+ neighbor_list = this._GetTotalNeighbor(target_index, search_direction);
1525
+ }
1526
+ if (focusable_target >= 0) {
1527
+ return template_list[focusable_target];
1528
+ } else if (target_index >= 0) {
1529
+ return this._GetNextLoopItem(target_index, offset, is_vertical);
1519
1530
  }
1520
- return template_list[next_index];
1521
1531
  }
1522
1532
  return null;
1523
1533
  }
1524
1534
 
1525
- _GetNextLoopItemHorizontal(index, offset) {
1535
+ //获取临近行的item
1536
+ _GetNearLineItem(index, offset, is_vertical) {
1526
1537
  const template_list = this._Template.List;
1527
- const base_item = template_list[index];
1528
- const center_y = base_item.centerYPos;
1529
- let direction = "right";
1538
+ let search_direction = is_vertical ? "right" : "bottom";
1539
+ let start_direction = is_vertical ? "top" : "left";
1530
1540
  if (offset > 0) {
1531
- direction = "left";
1532
- }
1533
- let found = false;
1534
- let next_index = -1;
1535
-
1536
- // 获得邻近点列表
1537
- let neighbor_list = template_list[index].neighborIndexList[direction];
1538
- if (template_list[index].tmpNeighborIndexList[direction].length > 0) {
1539
- neighbor_list = neighbor_list.concat(
1540
- template_list[index].tmpNeighborIndexList[direction]
1541
- );
1542
- }
1543
-
1544
- while (neighbor_list.length >= 1) {
1545
- for (let i = 0; i < neighbor_list.length; i++) {
1546
- next_index = neighbor_list[i];
1547
- const checking_item = template_list[next_index];
1548
- if (
1549
- center_y <= checking_item.yPos + checking_item.height - 1 &&
1550
- center_y >= checking_item.yPos
1551
- ) {
1552
- neighbor_list =
1553
- template_list[next_index].neighborIndexList[direction];
1554
- found = true;
1555
- break;
1541
+ search_direction = is_vertical ? "left" : "top";
1542
+ start_direction = is_vertical ? "bottom" : "right";
1543
+ }
1544
+ let start_index = -1;
1545
+ let neighbor_list = [];
1546
+ //寻找下一列的起始item
1547
+ neighbor_list = this._GetTotalNeighbor(index, search_direction);
1548
+ while (start_index < 0 && neighbor_list.length > 0) {
1549
+ for (let i of neighbor_list) {
1550
+ const n = this._GetTotalNeighbor(i, start_direction);
1551
+ if (n.length > 0) {
1552
+ return template_list[this._GetNearestItem(index, n)];
1553
+ } else {
1554
+ //TODO 是否要用递归
1555
+ neighbor_list = this._GetTotalNeighbor(i, search_direction);
1556
1556
  }
1557
1557
  }
1558
1558
  }
1559
-
1560
- if (found) {
1561
- if (!template_list[next_index].focusable) {
1562
- // 如果是占位符,则查找占位符的下一个
1563
- return this._GetNextLoopItemHorizontal(next_index, offset);
1564
- }
1565
- return template_list[next_index];
1566
- }
1567
1559
  return null;
1568
1560
  }
1569
1561