@shijiu/jsview-vue 1.9.888 → 1.9.915

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 (44) hide show
  1. package/package.json +1 -1
  2. package/utils/JsViewEngineWidget/MetroWidget/MetroWidget.vue +36 -67
  3. package/utils/JsViewEngineWidget/TemplateParser.js +146 -138
  4. package/utils/JsViewEngineWidget/WidgetCommon.js +2 -11
  5. package/utils/JsViewPlugin/BrowserPluginLoader.js +14 -0
  6. package/utils/JsViewPlugin/JsvPlayer/JsvPlayer.vue +1 -1
  7. package/utils/JsViewPlugin/JsvPlayer/version.js +19 -0
  8. package/utils/JsViewVueTools/JsvDynamicKeyFrames.js +1 -101
  9. package/utils/JsViewVueTools/JsvHashHistory.js +10 -10
  10. package/utils/JsViewVueTools/JsvImpactTracer.js +1 -1
  11. package/utils/JsViewVueTools/JsvStyleClass.js +1 -10
  12. package/utils/JsViewVueTools/JsvTextTools.js +7 -2
  13. package/utils/JsViewVueTools/TypeCheckAndSet.js +5 -5
  14. package/utils/JsViewVueTools/index.d.ts +1 -5
  15. package/utils/JsViewVueTools/index.js +0 -2
  16. package/utils/JsViewVueWidget/BrowserDebugWidget/BrowserQrcode.vue +173 -152
  17. package/utils/JsViewVueWidget/BrowserDebugWidget/BrowserSpray.vue +1 -1
  18. package/utils/JsViewVueWidget/BrowserDebugWidget/BrowserTextureAnim.vue +88 -51
  19. package/utils/JsViewVueWidget/BrowserDebugWidget/JsvApic/BrowserApic.vue +65 -63
  20. package/utils/JsViewVueWidget/JsvApic/JsvApic.vue +45 -82
  21. package/utils/JsViewVueWidget/JsvFilterView.vue +12 -17
  22. package/utils/JsViewVueWidget/JsvGrid.vue +10 -2
  23. package/utils/JsViewVueWidget/JsvInput/Cursor.vue +7 -5
  24. package/utils/JsViewVueWidget/JsvInput/JsvInput.vue +8 -60
  25. package/utils/JsViewVueWidget/JsvMarquee.vue +9 -12
  26. package/utils/JsViewVueWidget/JsvMaskClipDiv.vue +30 -24
  27. package/utils/JsViewVueWidget/JsvNativeSharedDiv.vue +1 -1
  28. package/utils/JsViewVueWidget/JsvPosterDiv.vue +2 -2
  29. package/utils/JsViewVueWidget/JsvPosterImage.vue +4 -4
  30. package/utils/JsViewVueWidget/JsvPreload/JsvPreload.vue +8 -8
  31. package/utils/JsViewVueWidget/JsvQrcode/JsvQrcode.vue +4 -4
  32. package/utils/JsViewVueWidget/JsvScaleTextBox.vue +1 -1
  33. package/utils/JsViewVueWidget/JsvSoundPool.js +1 -1
  34. package/utils/JsViewVueWidget/JsvSpray/JsvSpray.vue +13 -15
  35. package/utils/JsViewVueWidget/JsvSpriteAnim/JsvSpriteAnim.vue +1 -1
  36. package/utils/JsViewVueWidget/JsvSwiper/JsvSwiper.vue +115 -111
  37. package/utils/JsViewVueWidget/JsvSwiper3D/JsvSwiper.vue +1 -1
  38. package/utils/JsViewVueWidget/JsvTextBox.vue +38 -16
  39. package/utils/JsViewVueWidget/JsvTextureAnim/JsvTextureAnim.vue +16 -12
  40. package/utils/JsViewVueWidget/JsvTransparentDiv.vue +1 -1
  41. package/utils/JsViewVueWidget/JsvVisibleSensor/JsvVisibleSensor.vue +3 -3
  42. package/utils/JsViewVueWidget/JsvVisibleSensor/index.js +0 -3
  43. package/utils/JsViewVueWidget/index.js +8 -13
  44. package/utils/JsViewVueWidget/utils/text.js +3 -4
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shijiu/jsview-vue",
3
- "version": "1.9.888",
3
+ "version": "1.9.915",
4
4
  "license": "MIT",
5
5
  "repository": "system/jsview-framework",
6
6
  "author": "mengxk",
@@ -1,8 +1,6 @@
1
1
  <!--
2
2
  * @Author: ChenChanghua
3
3
  * @Date: 2021-09-22 16:08:58
4
- * @LastEditors: ChenChanghua
5
- * @LastEditTime: 2022-12-19 11:17:10
6
4
  * @Description: file content
7
5
  -->
8
6
 
@@ -23,13 +21,7 @@
23
21
  * name {string} 用于设置焦点的名称
24
22
  * padding {object} 控件内边距, 默认为{left: 0, right: 0, top: 0, bottom: 0}
25
23
  * direction {enum} (必选)控件方向 HORIZONTAL/VERTICAL
26
- * focusMoveType {int} 焦点移动的模式, 可通过 | 运算进行组合
27
- NO_ADJUST: 无特殊处理
28
- COLUMN_LOOP: 到达列首/尾后跳转到上/下一列, 只在水平滚动时生效
29
- ROW_LOOP: 到达行首/尾后跳转到上/下一行, 只在竖直滚动时生效
30
- COLUMN_FIND_NEAR: 一列中没有下一个元素时是否跳转到相邻列
31
- ROW_FIND_NEAR: 一行中没有下一个元素时是否跳转到相邻行
32
-
24
+ * loopFocus {boolean} 焦点到边界后自动转到下一行,默认false
33
25
  * initFocusId {int} 初始焦点,默认为0
34
26
  * slideSetting {SlideSetting} 页面滑动的设置, 目前SlideSetting有三个子类, 具体见 WidgetCommon 中的说明
35
27
  WholePageSlide
@@ -86,7 +78,6 @@
86
78
  * loadAll {boolean} 加载不显示的view,触控场景使用
87
79
  * flingPageWidth {}
88
80
  * flingPageEdge {}
89
- * disableClip {boolean} 取消显示范围的clipView
90
81
  * methods:
91
82
  getFocusBlockRef 获取此MetroWidget的 jsv-focus-block句柄,可以使用requestFocus完成获焦
92
83
 
@@ -182,7 +173,6 @@
182
173
 
183
174
  <script setup>
184
175
  /* eslint-disable */
185
- import { Forge } from "@shijiu/jsview/dom/jsv-forge-define"
186
176
  import {
187
177
  ref,
188
178
  reactive,
@@ -193,6 +183,7 @@ import {
193
183
  toRaw,
194
184
  nextTick,
195
185
  } from "vue";
186
+ import { Forge } from "@shijiu/jsview/dom/jsv-forge-define";
196
187
  import { TemplateParser, TemplateItemAdder } from "../TemplateParser";
197
188
  import { PageUpdater } from "./PageUpdater";
198
189
  import { SingleRangeModel } from "../RangeModel";
@@ -404,14 +395,6 @@ const props = defineProps({
404
395
  onScroll: {
405
396
  type: Function,
406
397
  },
407
- focusMoveType: {
408
- type: Number,
409
- default: 0,
410
- },
411
- disableClip: {
412
- type: Boolean,
413
- default: false,
414
- },
415
398
  });
416
399
 
417
400
  let dataUpdateToken = ref(0);
@@ -438,7 +421,7 @@ let itemRender = ref(!props.enableItemRenderBreak);
438
421
  let permanentItemList = [];
439
422
  let preUpdateVisibleStart = 0;
440
423
  let mounted = false;
441
- let focusNode = shallowRef(null);
424
+ let focusNode = ref(null);
442
425
  let pageRange = vertical ? props.height : props.width;
443
426
 
444
427
  let slideLock = false;
@@ -479,8 +462,8 @@ let visibleInfo = {
479
462
  },
480
463
  };
481
464
 
482
- let locateDiv = shallowRef(null);
483
- let slideDiv = shallowRef(null);
465
+ let locateDiv = ref(null);
466
+ let slideDiv = ref(null);
484
467
  let renderData = shallowRef([]);
485
468
  let slideDivLeft = ref(0);
486
469
  let slideDivTop = ref(0);
@@ -498,7 +481,7 @@ const _onFocusChange = (id) => {
498
481
  const _getCurrentId = () => {
499
482
  return {
500
483
  id: focusId,
501
- index: templateParser.IdToIndex(focusId),
484
+ index: templateParser.FocusIdToIndex(focusId),
502
485
  };
503
486
  };
504
487
 
@@ -578,7 +561,7 @@ const setFocusId = (id, needSlide = true, doAnim = false, extraSetting) => {
578
561
  let next_focus_item = templateParser.GetItemById(id);
579
562
  if (next_focus_item) {
580
563
  if (needSlide) {
581
- slideToItem(templateParser.IdToIndex(id), doAnim);
564
+ slideToItem(templateParser.FocusIdToIndex(id), doAnim);
582
565
  }
583
566
  let unlock = null;
584
567
  if (extraSetting) {
@@ -604,8 +587,8 @@ const setFocusId = (id, needSlide = true, doAnim = false, extraSetting) => {
604
587
  };
605
588
  _updateBlurItem();
606
589
  _updateFocusItem();
607
- onItemBlur(templateParser.IdToIndex(preFocusId));
608
- onItemFocus(templateParser.IdToIndex(focusId), preEdgeRect);
590
+ onItemBlur(templateParser.FocusIdToIndex(preFocusId));
591
+ onItemFocus(templateParser.FocusIdToIndex(focusId), preEdgeRect);
609
592
  unlock?.();
610
593
  }
611
594
  };
@@ -812,7 +795,7 @@ const refreshData = (force_update) => {
812
795
  dataUpdateToken.value++;
813
796
  pageUpdater.apply();
814
797
  _updateFocusItem();
815
- onItemFocus(templateParser.IdToIndex(focusId), null);
798
+ onItemFocus(templateParser.FocusIdToIndex(focusId), null);
816
799
  if (needSlide) {
817
800
  _slideTo(visibleInfo.start, null);
818
801
  } else if (need_update_content) {
@@ -1068,7 +1051,7 @@ const onKeyDown = (ev) => {
1068
1051
  _moveToNext(horizontal_direction, vertical_direction);
1069
1052
  break;
1070
1053
  case 13:
1071
- onItemClick(templateParser.IdToIndex(focusId));
1054
+ onItemClick(templateParser.FocusIdToIndex(focusId));
1072
1055
  break;
1073
1056
  default:
1074
1057
  //只接受上下左右确定键
@@ -1108,7 +1091,7 @@ const _onTemplateAdd = (item) => {
1108
1091
  this.slotMounted.value = true;
1109
1092
  if (callFocusAfterUpdate && this.data.id === focusId) {
1110
1093
  nextTick(() => {
1111
- onItemFocus(templateParser.IdToIndex(focusId), preEdgeRect);
1094
+ onItemFocus(templateParser.FocusIdToIndex(focusId), preEdgeRect);
1112
1095
  });
1113
1096
  callFocusAfterUpdate = false;
1114
1097
  }
@@ -1203,19 +1186,14 @@ const _onCustomerEvent = (ev) => {
1203
1186
  direction = 1;
1204
1187
  }
1205
1188
  }
1206
- let item_layout = getPositionRelativeToView(
1207
- item_div,
1208
- toRaw(locateDiv.value)
1209
- );
1189
+ const item_layout = item_div.jsvGetRelativePosition(toRaw(locateDiv.value));
1210
1190
 
1211
1191
  let obj = {
1212
1192
  xPos: item_layout.left,
1213
1193
  yPos: item_layout.top,
1214
1194
  width: item_layout.width,
1215
1195
  height: item_layout.height,
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),
1196
+ index: templateParser.FocusIdToIndex(focusId),
1219
1197
  };
1220
1198
 
1221
1199
  let cur_slide = _calculateVisibleStart(obj, direction);
@@ -1261,14 +1239,15 @@ const _moveToNext = (
1261
1239
  item_edge_rect
1262
1240
  ) => {
1263
1241
  let cur_focus_item = templateParser.GetItemById(focusId);
1264
- let next_focus_item = templateParser.GetNextItem(
1242
+ let next_item_id = templateParser.GetNextItem(
1265
1243
  focusId,
1266
1244
  vertical_direction,
1267
1245
  horizontal_direction,
1268
- props.focusMoveType
1246
+ props.loopFocus
1269
1247
  );
1270
- if (next_focus_item !== null) {
1248
+ if (next_item_id >= 0) {
1271
1249
  preFocusId = focusId;
1250
+ let next_focus_item = templateParser.GetItemById(next_item_id);
1272
1251
  templateItemAdder.tryAddItem(next_focus_item, 1);
1273
1252
  focusId = next_focus_item.id;
1274
1253
 
@@ -1277,7 +1256,8 @@ const _moveToNext = (
1277
1256
 
1278
1257
  let cur_visible_start = _calculateVisibleStart(next_focus_item, direction);
1279
1258
  if (
1280
- !innerData[templateParser.IdToIndex(focusId)].itemConfig?.takeOverSlide &&
1259
+ !innerData[templateParser.FocusIdToIndex(next_item_id)].itemConfig
1260
+ ?.takeOverSlide &&
1281
1261
  visibleInfo.start !== cur_visible_start
1282
1262
  ) {
1283
1263
  if (next_focus_item.doSlide) {
@@ -1299,7 +1279,7 @@ const _moveToNext = (
1299
1279
  1,
1300
1280
  visibleInfo.endWithPadding + props.keepTraceRange * pageRange
1301
1281
  ),
1302
- next_focus_item.id,
1282
+ next_item_id,
1303
1283
  false,
1304
1284
  permanentItemList
1305
1285
  );
@@ -1309,7 +1289,7 @@ const _moveToNext = (
1309
1289
  templateParser,
1310
1290
  cur_visible_start,
1311
1291
  cur_visible_start + visibleInfo.range + visibleInfo.padding.end - 1,
1312
- next_focus_item.id,
1292
+ next_item_id,
1313
1293
  false,
1314
1294
  permanentItemList
1315
1295
  );
@@ -1348,8 +1328,8 @@ const _moveToNext = (
1348
1328
  preEdgeRect = rect;
1349
1329
  _updateBlurItem();
1350
1330
  _updateFocusItem();
1351
- onItemBlur(templateParser.IdToIndex(preFocusId));
1352
- onItemFocus(templateParser.IdToIndex(focusId), preEdgeRect);
1331
+ onItemBlur(templateParser.FocusIdToIndex(preFocusId));
1332
+ onItemFocus(templateParser.FocusIdToIndex(focusId), preEdgeRect);
1353
1333
  } else {
1354
1334
  let x_off_set = props.direction === VERTICAL ? 0 : visibleInfo.start;
1355
1335
  let y_off_set = props.direction === VERTICAL ? visibleInfo.start : 0;
@@ -1373,7 +1353,7 @@ const _moveToNext = (
1373
1353
  height: cur_focus_item.height,
1374
1354
  };
1375
1355
  props.onEdge?.({ direction: edge, rect: rect });
1376
- innerData[templateParser.IdToIndex(focusId)].callbacks.onWidgetEdge?.({
1356
+ innerData[templateParser.FocusIdToIndex(focusId)].callbacks.onWidgetEdge?.({
1377
1357
  direction: edge,
1378
1358
  });
1379
1359
  }
@@ -1399,17 +1379,9 @@ const _calculateVisibleStart = (target_item, direction) => {
1399
1379
  );
1400
1380
  break;
1401
1381
  case SlideSetting.Type.WHOLE_PAGE:
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
-
1382
+ new_visible_start = templateParser.GetItem(target_item.pageHeadIndex)[
1383
+ pos_key
1384
+ ];
1413
1385
  break;
1414
1386
  case SlideSetting.Type.SEAMLESS:
1415
1387
  if (
@@ -1556,7 +1528,7 @@ const _onFocus = (params) => {
1556
1528
  enterFocusId = -1;
1557
1529
  enterFocusRect = null;
1558
1530
  _updateFocusItem();
1559
- onItemFocus(templateParser.IdToIndex(focusId), preEdgeRect);
1531
+ onItemFocus(templateParser.FocusIdToIndex(focusId), preEdgeRect);
1560
1532
  props.onFocus?.();
1561
1533
  };
1562
1534
 
@@ -1570,7 +1542,7 @@ const _onBlur = () => {
1570
1542
  }
1571
1543
  preFocusId = focusId;
1572
1544
  _updateBlurItem();
1573
- innerData[templateParser.IdToIndex(preFocusId)].callbacks.onBlur();
1545
+ innerData[templateParser.FocusIdToIndex(preFocusId)].callbacks.onBlur();
1574
1546
 
1575
1547
  props.onBlur?.();
1576
1548
  };
@@ -1583,11 +1555,11 @@ const _onSlideEnd = (event) => {
1583
1555
  };
1584
1556
 
1585
1557
  const _updateFocusItem = () => {
1586
- _setZIndex(templateParser.IdToIndex(focusId), innerData.length, true);
1558
+ _setZIndex(templateParser.FocusIdToIndex(focusId), innerData.length, true);
1587
1559
  };
1588
1560
 
1589
1561
  const _updateBlurItem = () => {
1590
- _setZIndex(templateParser.IdToIndex(preFocusId), 0, false);
1562
+ _setZIndex(templateParser.FocusIdToIndex(preFocusId), 0, false);
1591
1563
  };
1592
1564
 
1593
1565
  const _updateFocusByDragInfo = (viewX, viewY) => {
@@ -1757,9 +1729,7 @@ const _updatePosition = (x, y, anim_info) => {
1757
1729
  slide_animation.SetAnimationListener(
1758
1730
  new Forge.AnimationListener(anim_info.onstart, anim_info.onend, null)
1759
1731
  );
1760
- toRaw(slideDiv.value)
1761
- .jsvGetProxyView(true)
1762
- .StartAnimation(slide_animation);
1732
+ toRaw(slideDiv.value).jsvGetProxyView(true).StartAnimation(slide_animation);
1763
1733
  }
1764
1734
  _onScroll();
1765
1735
  }
@@ -1833,7 +1803,6 @@ templateParser = _getTemplateParser(
1833
1803
  props.supportHistoryPath,
1834
1804
  props.layoutType
1835
1805
  );
1836
-
1837
1806
  templateItemAdder = new TemplateItemAdder(
1838
1807
  templateParser,
1839
1808
  dataList,
@@ -1872,7 +1841,7 @@ slidePile = new Forge.RectArea(
1872
1841
  let init_focus_id = 0;
1873
1842
  let cur_visible_start = 0;
1874
1843
 
1875
- if (typeof props.initFocusId == "number") {
1844
+ if (typeof props.initFocusId == 'number') {
1876
1845
  templateItemAdder.tryAddItemById(props.initFocusId);
1877
1846
  const item = templateParser.GetItemById(props.initFocusId);
1878
1847
  if (item) {
@@ -1910,7 +1879,7 @@ onMounted(() => {
1910
1879
  _slideTo(visibleInfo.start, null);
1911
1880
  }
1912
1881
 
1913
- onItemFocus(templateParser.IdToIndex(focusId), preEdgeRect);
1882
+ onItemFocus(templateParser.FocusIdToIndex(focusId), preEdgeRect);
1914
1883
 
1915
1884
  if (props.enableItemRenderBreak) {
1916
1885
  nextTick(() => {
@@ -1944,7 +1913,7 @@ defineExpose(exportObject);
1944
1913
  top: top,
1945
1914
  width: width,
1946
1915
  height: height,
1947
- overflow: disableClip ? null : 'hidden',
1916
+ overflow: 'hidden',
1948
1917
  }"
1949
1918
  >
1950
1919
  <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, FocusMoveType } from "./WidgetCommon";
4
+ import { VERTICAL, HORIZONTAL } 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
- IdToIndex(id) {
1067
+ FocusIdToIndex(id) {
1068
1068
  return this._Template.IdsMap[id];
1069
1069
  }
1070
1070
 
@@ -1200,6 +1200,64 @@ 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
+ // }
1203
1261
  }
1204
1262
 
1205
1263
  /**
@@ -1212,76 +1270,47 @@ class TemplateParser {
1212
1270
  * @param {int} base_item_id Item的Id
1213
1271
  * @param {int} vertical_offset 纵向偏移(-1为向上,1为向下)
1214
1272
  * @param {int} horizontal_offset 横向偏移(-1为向左,1为向右)
1215
- * @param {int} focus_move_type 焦点移动设置
1273
+ * @param {bool} need_loop 循环查找
1216
1274
  * @return {int} 下一个Item的Id,-1为该方向未找到Item(到达边缘)
1217
1275
  * */
1218
- GetNextItem(
1219
- base_item_id,
1220
- vertical_offset,
1221
- horizontal_offset,
1222
- focus_move_type
1223
- ) {
1276
+ GetNextItem(base_item_id, vertical_offset, horizontal_offset, need_loop) {
1224
1277
  if (vertical_offset === 0 && horizontal_offset === 0)
1225
1278
  console.log("GetNextItem(): offset is 0");
1226
1279
  // Forge.ThrowError("GetNextItem(): offset is 0");
1227
1280
 
1228
1281
  if (vertical_offset !== 0 && horizontal_offset !== 0) {
1229
1282
  console.log(
1230
- "GetNextItem(): not support change vertical and horizontal at the same time"
1283
+ "GetNextItem(): not support change vertical and horizontal and the same time"
1231
1284
  );
1232
1285
  // Forge.ThrowError("GetNextItem(): not support change vertical and horizontal and the same time");
1233
1286
  }
1234
1287
 
1235
- const item_index = this.IdToIndex(base_item_id);
1288
+ const list_index = this._Template.IdsMap[base_item_id];
1236
1289
  const offset = vertical_offset !== 0 ? vertical_offset : horizontal_offset;
1237
1290
  let next_template_item = this._GetNextItem(
1238
- item_index,
1291
+ list_index,
1239
1292
  offset,
1240
1293
  vertical_offset !== 0
1241
1294
  );
1242
- const is_vertical = this._Template.Orient.type === VERTICAL;
1243
1295
 
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
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
1255
1301
  );
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
1302
+ } else {
1303
+ next_template_item = this._GetNextLoopItemHorizontal(
1304
+ list_index,
1305
+ horizontal_offset
1265
1306
  );
1266
1307
  }
1267
1308
  }
1268
1309
 
1269
1310
  if (next_template_item === null) {
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
- }
1311
+ return -1;
1282
1312
  }
1283
-
1284
- return next_template_item;
1313
+ return next_template_item.id;
1285
1314
  }
1286
1315
 
1287
1316
  _GetNextItem(index, offset, vertical) {
@@ -1447,115 +1476,94 @@ class TemplateParser {
1447
1476
  return null;
1448
1477
  }
1449
1478
 
1450
- _GetItemDistance(item1, item2) {
1451
- return (
1452
- Math.pow(item1.centerXPos - item2.centerXPos, 2) +
1453
- Math.pow(item1.centerYPos - item2.centerYPos, 2)
1454
- );
1455
- }
1456
-
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
- }
1474
- }
1475
- return nearest_index;
1476
- }
1477
-
1478
- _GetNextLoopItem(index, offset, is_vertical) {
1479
+ _GetNextLoopItemVertical(index, offset) {
1479
1480
  const template_list = this._Template.List;
1480
1481
  const base_item = template_list[index];
1481
- let search_direction = is_vertical ? "right" : "bottom";
1482
- let start_direction = is_vertical ? "top" : "left";
1482
+ const center_x = base_item.centerXPos;
1483
+ let direction = "bottom";
1484
+ // Normalize offset
1483
1485
  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;
1486
+ direction = "top";
1487
+ }
1488
+ let found = false;
1489
+ let next_index = -1;
1490
+
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
+ );
1497
+ }
1498
+
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;
1497
1510
  break;
1498
- } else {
1499
- //TODO 是否要用递归
1500
- neighbor_list = this._GetTotalNeighbor(i, search_direction);
1501
1511
  }
1502
1512
  }
1503
1513
  }
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
- }
1517
1514
 
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);
1515
+ if (found) {
1516
+ if (!template_list[next_index].focusable) {
1517
+ // 如果是占位符,则查找占位符的下一个
1518
+ return this._GetNextLoopItemVertical(next_index, offset);
1530
1519
  }
1520
+ return template_list[next_index];
1531
1521
  }
1532
1522
  return null;
1533
1523
  }
1534
1524
 
1535
- //获取临近行的item
1536
- _GetNearLineItem(index, offset, is_vertical) {
1525
+ _GetNextLoopItemHorizontal(index, offset) {
1537
1526
  const template_list = this._Template.List;
1538
- let search_direction = is_vertical ? "right" : "bottom";
1539
- let start_direction = is_vertical ? "top" : "left";
1527
+ const base_item = template_list[index];
1528
+ const center_y = base_item.centerYPos;
1529
+ let direction = "right";
1540
1530
  if (offset > 0) {
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);
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;
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
+ }
1559
1567
  return null;
1560
1568
  }
1561
1569