@shijiu/jsview-vue 2.0.1021 → 2.0.1073
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +4 -3
- package/utils/JsViewEngineWidget/CheckType.js +82 -0
- package/utils/JsViewEngineWidget/MetroWidget/AnimationManager.ts +72 -0
- package/utils/JsViewEngineWidget/MetroWidget/Const.ts +24 -0
- package/utils/JsViewEngineWidget/MetroWidget/ListWidget.vue +295 -0
- package/utils/JsViewEngineWidget/MetroWidget/MetroWidget.vue +110 -1651
- package/utils/JsViewEngineWidget/MetroWidget/MetroWidgetSetup.js +1867 -0
- package/utils/JsViewEngineWidget/MetroWidget/PageUpdater.ts +111 -0
- package/utils/JsViewEngineWidget/MetroWidget/RenderItem.ts +153 -0
- package/utils/JsViewEngineWidget/MetroWidget/VisibleInfo.ts +43 -0
- package/utils/JsViewEngineWidget/MetroWidget/WidgetRectInfo.ts +49 -0
- package/utils/JsViewEngineWidget/TemplateParser/CommonMetroTemplate.ts +1424 -0
- package/utils/JsViewEngineWidget/TemplateParser/Fence.ts +135 -0
- package/utils/JsViewEngineWidget/TemplateParser/ListMetroTemplate.ts +177 -0
- package/utils/JsViewEngineWidget/TemplateParser/MetroTemplate.ts +334 -0
- package/utils/JsViewEngineWidget/TemplateParser/TemplateItemAdder.ts +147 -0
- package/utils/JsViewEngineWidget/TemplateParser/index.ts +4 -0
- package/utils/JsViewEngineWidget/{WidgetCommon.js → WidgetCommon.ts} +64 -71
- package/utils/JsViewEngineWidget/index.js +2 -1
- package/utils/JsViewPlugin/JsvAudio/AudioProxy.js +26 -1
- package/utils/JsViewPlugin/JsvAudio/JsvAudio.vue +120 -133
- package/utils/JsViewPlugin/JsvAudio/JsvAudioBrowser.vue +11 -7
- package/utils/JsViewPlugin/JsvPlayer/GetVersion.js +1 -1
- package/utils/JsViewPlugin/JsvPlayer/JsvPlayerBrowser.vue +379 -41
- package/utils/JsViewPlugin/JsvPlayer/version.mjs +5 -5
- package/utils/JsViewVueTools/JsvHashHistory.js +2 -1
- package/utils/JsViewVueWidget/JsvRadarChart.vue +220 -0
- package/utils/JsViewVueWidget/JsvSystemAudio.vue +76 -44
- package/utils/JsViewVueWidget/index.js +1 -0
- package/utils/JsViewEngineWidget/MetroWidget/Const.js +0 -11
- package/utils/JsViewEngineWidget/MetroWidget/PageUpdater.js +0 -136
- package/utils/JsViewEngineWidget/MetroWidget/ToolFunctions.js +0 -18
- package/utils/JsViewEngineWidget/TemplateParser.js +0 -2004
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
* height {int} (必选)控件的高
|
|
18
18
|
* layoutType {String} 布局的类型, 目前支持 "relative"(默认)|"absolute", relative为自动布局,
|
|
19
19
|
absolute为依据measures中给的top, left布局
|
|
20
|
-
*
|
|
20
|
+
*
|
|
21
21
|
* name {string} 用于设置焦点的名称
|
|
22
22
|
* padding {object} 控件内边距, 默认为{left: 0, right: 0, top: 0, bottom: 0}
|
|
23
23
|
* direction {enum} (必选)控件方向 HORIZONTAL/VERTICAL
|
|
@@ -85,6 +85,7 @@
|
|
|
85
85
|
* flingPageWidth {}
|
|
86
86
|
* flingPageEdge {}
|
|
87
87
|
* disableClip {boolean} 取消显示范围的clipView
|
|
88
|
+
|
|
88
89
|
* methods:
|
|
89
90
|
getFocusBlockRef 获取此MetroWidget的 jsv-focus-block句柄,可以使用requestFocus完成获焦
|
|
90
91
|
|
|
@@ -131,10 +132,19 @@
|
|
|
131
132
|
@params {int} type 锁的类型, 通过|来实现多个类型的复合
|
|
132
133
|
SLIDE: 滚动动画锁
|
|
133
134
|
CHILD_SLIDE_EVENT: 子组件发送的滚动事件锁
|
|
135
|
+
ON_KEY_DOWN: 按键锁
|
|
134
136
|
@return {function} 解锁的函数
|
|
135
137
|
unlock
|
|
136
138
|
@description 解锁
|
|
137
139
|
@params {int} type 参考lock的type参数
|
|
140
|
+
moveFocus
|
|
141
|
+
@description 移动焦点
|
|
142
|
+
@params {int | string | EdgeDirection} 可传三种类型的值:
|
|
143
|
+
1. 方向键的数值 37|38|39|40,
|
|
144
|
+
2. 字符串 left|top|right|bottom,
|
|
145
|
+
3. EdgeDirection
|
|
146
|
+
getCustomerDataSize
|
|
147
|
+
@description 获取用户数据长度
|
|
138
148
|
slots:
|
|
139
149
|
renderItem: 该slot用于描画每个单元格
|
|
140
150
|
background: 该slot描画在item后, 一般用于描画需要跟随MetroWidget滚动的内容
|
|
@@ -153,6 +163,11 @@
|
|
|
153
163
|
获取当前焦点信息,id 为在可获得焦点元素列表中的索引,index 为在所有元素列表中的索引
|
|
154
164
|
slideTo: {Function} (targetPosition : int, doAnim : Boolean) => void
|
|
155
165
|
滚动到指定位置,注意这个位置是 item 的布局坐标,另外当某些item需要接管滚动时,itemConfig中takeOverSlide要为true。
|
|
166
|
+
updateItemSize: {(index: number, newSize: {width: number, height: number}, anchor: number, animInfo: {duration: number, onEnd: Function}) => void} 更新item的尺寸, 目前仅在list模式下可用.
|
|
167
|
+
params:
|
|
168
|
+
index: 更新item的index,
|
|
169
|
+
anchor: item大小变化时不动点的位置, 值为0-1
|
|
170
|
+
|
|
156
171
|
}
|
|
157
172
|
* onItemEdge: 若单元格内另有可接管按键的控件(如MetroWidget),该控件到达边缘需要通知MetroWidget时的回调
|
|
158
173
|
* onAction: 单元格内控件需要通过onAction.register方法向MetroWidget注册 item 的回调,回调函数有
|
|
@@ -183,101 +198,14 @@
|
|
|
183
198
|
-->
|
|
184
199
|
|
|
185
200
|
<script setup>
|
|
186
|
-
|
|
187
|
-
import {
|
|
188
|
-
ref,
|
|
189
|
-
reactive,
|
|
190
|
-
shallowRef,
|
|
191
|
-
onMounted,
|
|
192
|
-
onBeforeUnmount,
|
|
193
|
-
onUpdated,
|
|
194
|
-
toRaw,
|
|
195
|
-
nextTick,
|
|
196
|
-
} from "vue";
|
|
197
|
-
import { Forge } from "@shijiu/jsview/dom/jsv-forge-define";
|
|
198
|
-
import { TemplateParser, TemplateItemAdder } from "../TemplateParser";
|
|
199
|
-
import { PageUpdater } from "./PageUpdater";
|
|
200
|
-
import { SingleRangeModel } from "../RangeModel";
|
|
201
|
-
import Dispatcher from "./Dispatcher";
|
|
202
|
-
import { METRO_WIDGET } from "./Const";
|
|
201
|
+
import { ref, shallowRef, computed } from "vue";
|
|
202
|
+
import { setup, RENDER_ITEM_BREAK_KEY } from "./MetroWidgetSetup";
|
|
203
203
|
import {
|
|
204
|
-
EdgeDirection,
|
|
205
204
|
VERTICAL,
|
|
206
205
|
HORIZONTAL,
|
|
207
|
-
getPositionRelativeToView,
|
|
208
206
|
SlideSetting,
|
|
209
207
|
SeamlessSlide,
|
|
210
208
|
} from "../WidgetCommon";
|
|
211
|
-
import { bindFunctions } from "./ToolFunctions";
|
|
212
|
-
|
|
213
|
-
const _getPadding = function (padding) {
|
|
214
|
-
return Object.assign(
|
|
215
|
-
{
|
|
216
|
-
left: 0,
|
|
217
|
-
right: 0,
|
|
218
|
-
top: 0,
|
|
219
|
-
bottom: 0,
|
|
220
|
-
},
|
|
221
|
-
padding
|
|
222
|
-
);
|
|
223
|
-
};
|
|
224
|
-
|
|
225
|
-
const _getTemplateParser = function (
|
|
226
|
-
width,
|
|
227
|
-
height,
|
|
228
|
-
direction,
|
|
229
|
-
padding,
|
|
230
|
-
support_history_path,
|
|
231
|
-
layout_type
|
|
232
|
-
) {
|
|
233
|
-
let fixed_padding = _getPadding(padding);
|
|
234
|
-
let page_size;
|
|
235
|
-
let line_max;
|
|
236
|
-
if (direction === VERTICAL) {
|
|
237
|
-
line_max = width - fixed_padding.left - fixed_padding.right;
|
|
238
|
-
page_size = height - fixed_padding.top - fixed_padding.bottom;
|
|
239
|
-
} else {
|
|
240
|
-
line_max = height - fixed_padding.top - fixed_padding.bottom;
|
|
241
|
-
page_size = width - fixed_padding.left - fixed_padding.right;
|
|
242
|
-
}
|
|
243
|
-
return new TemplateParser(
|
|
244
|
-
direction,
|
|
245
|
-
line_max,
|
|
246
|
-
page_size,
|
|
247
|
-
layout_type,
|
|
248
|
-
support_history_path
|
|
249
|
-
);
|
|
250
|
-
};
|
|
251
|
-
|
|
252
|
-
// direction key 是 vertical 的值
|
|
253
|
-
const directionFreeKeyMap = {
|
|
254
|
-
pos: {
|
|
255
|
-
true: "yPos",
|
|
256
|
-
false: "xPos",
|
|
257
|
-
},
|
|
258
|
-
size: {
|
|
259
|
-
true: "height",
|
|
260
|
-
false: "width",
|
|
261
|
-
},
|
|
262
|
-
neighbor: {
|
|
263
|
-
true: {
|
|
264
|
-
1: "bottom",
|
|
265
|
-
"-1": "top",
|
|
266
|
-
},
|
|
267
|
-
false: {
|
|
268
|
-
1: "bottom",
|
|
269
|
-
"-1": "top",
|
|
270
|
-
},
|
|
271
|
-
},
|
|
272
|
-
margin: {
|
|
273
|
-
true: "marginBottom",
|
|
274
|
-
false: "marginRight",
|
|
275
|
-
},
|
|
276
|
-
center: {
|
|
277
|
-
true: "centerYPos",
|
|
278
|
-
false: "centerXPos",
|
|
279
|
-
},
|
|
280
|
-
};
|
|
281
209
|
|
|
282
210
|
const props = defineProps({
|
|
283
211
|
padding: {
|
|
@@ -416,1525 +344,46 @@ const props = defineProps({
|
|
|
416
344
|
},
|
|
417
345
|
});
|
|
418
346
|
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
set start(value) {
|
|
459
|
-
this._start = value;
|
|
460
|
-
this._startMax = Math.max(this._start, this._startMax);
|
|
461
|
-
},
|
|
462
|
-
|
|
463
|
-
get start() {
|
|
464
|
-
return this._start;
|
|
465
|
-
},
|
|
466
|
-
|
|
467
|
-
get end() {
|
|
468
|
-
return this._start + this.range - 1;
|
|
469
|
-
},
|
|
470
|
-
|
|
471
|
-
get startMax() {
|
|
472
|
-
return this._startMax;
|
|
473
|
-
},
|
|
474
|
-
|
|
475
|
-
get startWithPadding() {
|
|
476
|
-
return this._start - this.padding.start;
|
|
477
|
-
},
|
|
478
|
-
|
|
479
|
-
get endWithPadding() {
|
|
480
|
-
return this._start + this.range + this.padding.end - 1;
|
|
481
|
-
},
|
|
482
|
-
};
|
|
483
|
-
|
|
484
|
-
let locateDiv = shallowRef(null);
|
|
485
|
-
let slideDiv = shallowRef(null);
|
|
486
|
-
let renderData = shallowRef([]);
|
|
487
|
-
let slideDivLeft = ref(0);
|
|
488
|
-
let slideDivTop = ref(0);
|
|
489
|
-
let callFocusAfterUpdate = false;
|
|
490
|
-
let renderBreakKey = props.enableItemRenderBreak
|
|
491
|
-
? "__QcodeJsviewMetroWidgetSlot"
|
|
492
|
-
: "";
|
|
493
|
-
let pageUpdateToken = ref(0);
|
|
494
|
-
|
|
495
|
-
//methods
|
|
496
|
-
const _onFocusChange = (id) => {
|
|
497
|
-
props.onFocusChange?.(id);
|
|
498
|
-
};
|
|
499
|
-
|
|
500
|
-
const _getCurrentId = () => {
|
|
501
|
-
return {
|
|
502
|
-
id: focusId,
|
|
503
|
-
index: templateParser.IdToIndex(focusId),
|
|
504
|
-
};
|
|
505
|
-
};
|
|
506
|
-
|
|
507
|
-
const _getPosition = (index) => {
|
|
508
|
-
let item = templateParser.GetItem(index);
|
|
509
|
-
let x_offset = props.direction === VERTICAL ? 0 : -visibleInfo.start;
|
|
510
|
-
let y_offset = props.direction === VERTICAL ? -visibleInfo.start : 0;
|
|
511
|
-
return {
|
|
512
|
-
left: item.xPos + x_offset,
|
|
513
|
-
top: item.yPos + y_offset,
|
|
514
|
-
width: item.width,
|
|
515
|
-
height: item.height,
|
|
516
|
-
};
|
|
517
|
-
};
|
|
518
|
-
|
|
519
|
-
const _getTemplatePosition = (index) => {
|
|
520
|
-
let item = templateParser.GetItem(index);
|
|
521
|
-
return {
|
|
522
|
-
left: item.xPos,
|
|
523
|
-
top: item.yPos,
|
|
524
|
-
width: item.width,
|
|
525
|
-
height: item.height,
|
|
526
|
-
};
|
|
527
|
-
};
|
|
528
|
-
|
|
529
|
-
const _dispatchEvent = (event) => {
|
|
530
|
-
switch (event.type) {
|
|
531
|
-
case Dispatcher.Type.setEnterFocusId:
|
|
532
|
-
setEnterFocusId(event.data);
|
|
533
|
-
break;
|
|
534
|
-
case Dispatcher.Type.setEnterFocusRect:
|
|
535
|
-
setEnterFocusRect(event.data);
|
|
536
|
-
break;
|
|
537
|
-
case Dispatcher.Type.updateItem:
|
|
538
|
-
break;
|
|
539
|
-
case Dispatcher.Type.slideToItem:
|
|
540
|
-
if (event.data) {
|
|
541
|
-
slideToItem(event.data?.id, event.data?.doAnim);
|
|
542
|
-
}
|
|
543
|
-
break;
|
|
544
|
-
case Dispatcher.Type.setFocusId:
|
|
545
|
-
setFocusId(event.data?.id, event.data?.needSlide, event.data?.doAnim);
|
|
546
|
-
break;
|
|
547
|
-
default:
|
|
548
|
-
break;
|
|
549
|
-
}
|
|
550
|
-
};
|
|
551
|
-
|
|
552
|
-
const onItemClick = (index) => {
|
|
553
|
-
if (isFocus && innerData[index]?.callbacks.callable("onClick")) {
|
|
554
|
-
innerData[index].callbacks.onClick();
|
|
555
|
-
}
|
|
556
|
-
};
|
|
557
|
-
|
|
558
|
-
const onItemBlur = (index) => {
|
|
559
|
-
if (isFocus && innerData[index]?.callbacks.callable("onBlur")) {
|
|
560
|
-
innerData[index].callbacks.onBlur();
|
|
561
|
-
}
|
|
562
|
-
};
|
|
563
|
-
|
|
564
|
-
const onItemFocus = (index, rect) => {
|
|
565
|
-
if (isFocus) {
|
|
566
|
-
if (innerData[index]) {
|
|
567
|
-
_itemOnFocusSideEffect(innerData[index], rect);
|
|
568
|
-
if (innerData[index].callbacks.callable("onFocus")) {
|
|
569
|
-
innerData[index].callbacks.onFocus(rect);
|
|
570
|
-
} else {
|
|
571
|
-
callFocusAfterUpdate = true;
|
|
572
|
-
}
|
|
573
|
-
}
|
|
574
|
-
}
|
|
575
|
-
};
|
|
576
|
-
|
|
577
|
-
const setFocusId = (id, needSlide = true, doAnim = false, extraSetting) => {
|
|
578
|
-
if (id == focusId) {
|
|
579
|
-
return;
|
|
580
|
-
}
|
|
581
|
-
templateItemAdder.tryAddItemById(id);
|
|
582
|
-
let next_focus_item = templateParser.GetItemById(id);
|
|
583
|
-
if (next_focus_item) {
|
|
584
|
-
if (needSlide) {
|
|
585
|
-
slideToItem(templateParser.IdToIndex(id), doAnim);
|
|
586
|
-
}
|
|
587
|
-
let unlock = null;
|
|
588
|
-
if (extraSetting) {
|
|
589
|
-
if (extraSetting.lockChildSlideEvent) {
|
|
590
|
-
unlock = lock(METRO_WIDGET.CHILD_SLIDE_EVENT);
|
|
591
|
-
}
|
|
592
|
-
}
|
|
593
|
-
|
|
594
|
-
const cur_focus_item = templateParser.GetItemById(focusId);
|
|
595
|
-
preFocusId = focusId;
|
|
596
|
-
focusId = next_focus_item.id;
|
|
597
|
-
|
|
598
|
-
let x_off_set = cur_focus_item.xPos - next_focus_item.xPos;
|
|
599
|
-
let y_off_set = cur_focus_item.yPos - next_focus_item.yPos;
|
|
600
|
-
preEdgeRect = {
|
|
601
|
-
direction: null,
|
|
602
|
-
rect: {
|
|
603
|
-
x: x_off_set,
|
|
604
|
-
y: y_off_set,
|
|
605
|
-
width: cur_focus_item.width,
|
|
606
|
-
height: cur_focus_item.height,
|
|
607
|
-
},
|
|
608
|
-
};
|
|
609
|
-
_updateBlurItem();
|
|
610
|
-
_updateFocusItem();
|
|
611
|
-
onItemBlur(templateParser.IdToIndex(preFocusId));
|
|
612
|
-
onItemFocus(templateParser.IdToIndex(focusId), preEdgeRect);
|
|
613
|
-
unlock?.();
|
|
614
|
-
}
|
|
615
|
-
};
|
|
616
|
-
|
|
617
|
-
const lock = (type) => {
|
|
618
|
-
const unlocker = [];
|
|
619
|
-
if (type & METRO_WIDGET.SLIDE) {
|
|
620
|
-
slideLock = true;
|
|
621
|
-
unlocker.push(() => {
|
|
622
|
-
slideLock = false;
|
|
623
|
-
});
|
|
624
|
-
}
|
|
625
|
-
if (type & METRO_WIDGET.CHILD_SLIDE_EVENT) {
|
|
626
|
-
childSlideEventLock = true;
|
|
627
|
-
unlocker.push(() => {
|
|
628
|
-
childSlideEventLock = false;
|
|
629
|
-
});
|
|
630
|
-
}
|
|
631
|
-
return () => {
|
|
632
|
-
unlocker.map((item) => {
|
|
633
|
-
item();
|
|
634
|
-
});
|
|
635
|
-
};
|
|
636
|
-
};
|
|
637
|
-
|
|
638
|
-
const unlock = (type) => {
|
|
639
|
-
if (type & METRO_WIDGET.SLIDE) {
|
|
640
|
-
slideLock = true;
|
|
641
|
-
}
|
|
642
|
-
if (type & METRO_WIDGET.CHILD_SLIDE_EVENT) {
|
|
643
|
-
childSlideEventLock = true;
|
|
644
|
-
}
|
|
645
|
-
};
|
|
646
|
-
|
|
647
|
-
const getFocusBlockRef = () => {
|
|
648
|
-
return toRaw(focusNode.value);
|
|
649
|
-
};
|
|
650
|
-
|
|
651
|
-
const setEnterFocusId = (id) => {
|
|
652
|
-
templateItemAdder.tryAddItemById(id);
|
|
653
|
-
enterFocusId = id;
|
|
654
|
-
};
|
|
655
|
-
|
|
656
|
-
const setEnterFocusRect = (rect) => {
|
|
657
|
-
enterFocusRect = rect;
|
|
658
|
-
};
|
|
659
|
-
|
|
660
|
-
const slideTo = (position, doAnim) => {
|
|
661
|
-
templateItemAdder.tryAddItemByPosition(position);
|
|
662
|
-
if (
|
|
663
|
-
typeof position !== "undefined" &&
|
|
664
|
-
position != null &&
|
|
665
|
-
visibleInfo.start !== position
|
|
666
|
-
) {
|
|
667
|
-
visibleInfo.start = position;
|
|
668
|
-
let animObj = null;
|
|
669
|
-
if (doAnim) {
|
|
670
|
-
animObj = {
|
|
671
|
-
easing: props.slideSetting.Easing,
|
|
672
|
-
onstart: null,
|
|
673
|
-
speed: props.slideSetting.Speed,
|
|
674
|
-
onend: _onSlideEnd,
|
|
675
|
-
};
|
|
676
|
-
}
|
|
677
|
-
_slideTo(visibleInfo.start, animObj);
|
|
678
|
-
|
|
679
|
-
pageUpdater.update(
|
|
680
|
-
templateParser,
|
|
681
|
-
visibleInfo.startWithPadding,
|
|
682
|
-
visibleInfo.endWithPadding,
|
|
683
|
-
focusId,
|
|
684
|
-
false,
|
|
685
|
-
permanentItemList
|
|
686
|
-
);
|
|
687
|
-
if (doAnim) {
|
|
688
|
-
pageUpdater.applyTmp();
|
|
689
|
-
} else {
|
|
690
|
-
pageUpdater.apply();
|
|
691
|
-
}
|
|
692
|
-
}
|
|
693
|
-
};
|
|
694
|
-
|
|
695
|
-
const slideToItem = (index, doAnim) => {
|
|
696
|
-
templateItemAdder.tryAddItemByIndex(index);
|
|
697
|
-
const targetItem = templateParser.GetItem(index);
|
|
698
|
-
if (targetItem) {
|
|
699
|
-
const direction = index - preAnchorItemIndex > 0 ? 1 : -1;
|
|
700
|
-
const visible_start = _calculateVisibleStart(targetItem, direction);
|
|
701
|
-
slideTo(visible_start, doAnim);
|
|
702
|
-
}
|
|
703
|
-
};
|
|
704
|
-
|
|
705
|
-
const refreshData = (force_update) => {
|
|
706
|
-
//由于data不支持reactive, 因此数据的更新只通过provideData
|
|
707
|
-
if (!props.provideData) {
|
|
708
|
-
console.error("refreshData: provideData is null.");
|
|
709
|
-
return;
|
|
710
|
-
}
|
|
711
|
-
let _force_update = force_update;
|
|
712
|
-
let template_list = templateParser.GetTemplate().List;
|
|
713
|
-
if (!template_list || template_list.length === 0) {
|
|
714
|
-
_force_update = true;
|
|
715
|
-
}
|
|
716
|
-
let new_list = toRaw(props.provideData());
|
|
717
|
-
let needSlide = false;
|
|
718
|
-
if (focusId >= new_list.length) {
|
|
719
|
-
focusId = 0;
|
|
720
|
-
preFocusId = -1;
|
|
721
|
-
if (visibleInfo.start !== 0) {
|
|
722
|
-
visibleInfo.start = 0;
|
|
723
|
-
needSlide = true;
|
|
724
|
-
}
|
|
725
|
-
}
|
|
726
|
-
let new_index = 0;
|
|
727
|
-
if (!_force_update) {
|
|
728
|
-
for (new_index = 0; new_index < new_list.length; ++new_index) {
|
|
729
|
-
let already_add = false;
|
|
730
|
-
for (let j = 0; j < template_list.length; ++j) {
|
|
731
|
-
if (new_list[new_index] === template_list[j].data) {
|
|
732
|
-
already_add = true;
|
|
733
|
-
break;
|
|
734
|
-
}
|
|
735
|
-
}
|
|
736
|
-
if (!already_add) {
|
|
737
|
-
break;
|
|
738
|
-
}
|
|
739
|
-
}
|
|
740
|
-
}
|
|
741
|
-
let need_update_content = false;
|
|
742
|
-
if (!_force_update && new_index === template_list.length) {
|
|
743
|
-
//原始数据都在
|
|
744
|
-
if (new_index !== new_list.length) {
|
|
745
|
-
//增加数据
|
|
746
|
-
need_update_content = true;
|
|
747
|
-
templateItemAdder.updateData(new_list);
|
|
748
|
-
} else {
|
|
749
|
-
//数据没变
|
|
750
|
-
}
|
|
751
|
-
} else {
|
|
752
|
-
pageUpdateToken.value++;
|
|
753
|
-
//数据更改
|
|
754
|
-
permanentItemList = [];
|
|
755
|
-
need_update_content = true;
|
|
756
|
-
templateParser = _getTemplateParser(
|
|
757
|
-
props.width,
|
|
758
|
-
props.height,
|
|
759
|
-
props.direction,
|
|
760
|
-
props.padding,
|
|
761
|
-
props.supportHistoryPath,
|
|
762
|
-
props.layoutType
|
|
763
|
-
);
|
|
764
|
-
innerData = [];
|
|
765
|
-
dataList = new_list;
|
|
766
|
-
templateItemAdder = new TemplateItemAdder(
|
|
767
|
-
templateParser,
|
|
768
|
-
dataList,
|
|
769
|
-
props.measures,
|
|
770
|
-
pageRange,
|
|
771
|
-
_onTemplateAdd,
|
|
772
|
-
props.name
|
|
773
|
-
);
|
|
774
|
-
}
|
|
775
|
-
if (need_update_content) {
|
|
776
|
-
if (props.onScroll) {
|
|
777
|
-
templateItemAdder.tryAddItemByIndex(dataList.length - 1);
|
|
778
|
-
} else {
|
|
779
|
-
templateItemAdder.tryAddItemById(focusId);
|
|
780
|
-
}
|
|
781
|
-
let template_list = templateParser.GetTemplate().List;
|
|
782
|
-
let last_item = template_list[template_list.length - 1];
|
|
783
|
-
touchListener = _getTouchListener();
|
|
784
|
-
innerPadding = _getPadding(props.padding);
|
|
785
|
-
touchContainerW.value =
|
|
786
|
-
props.direction === VERTICAL
|
|
787
|
-
? props.width
|
|
788
|
-
: last_item
|
|
789
|
-
? last_item.xPos + last_item.width
|
|
790
|
-
: 0;
|
|
791
|
-
touchContainerH.value =
|
|
792
|
-
props.direction === VERTICAL
|
|
793
|
-
? last_item
|
|
794
|
-
? last_item.yPos + last_item.height
|
|
795
|
-
: 0
|
|
796
|
-
: props.height;
|
|
797
|
-
slidePile = new Forge.RectArea(
|
|
798
|
-
0,
|
|
799
|
-
0,
|
|
800
|
-
props.width - innerPadding.left - innerPadding.right,
|
|
801
|
-
props.height - innerPadding.top - innerPadding.bottom
|
|
802
|
-
);
|
|
803
|
-
dragDirection =
|
|
804
|
-
props.direction === VERTICAL
|
|
805
|
-
? Forge.DragSetting.DIRECTION_VERTICAL
|
|
806
|
-
: Forge.DragSetting.DIRECTION_HORIZONTAL;
|
|
807
|
-
}
|
|
808
|
-
pageUpdater.update(
|
|
809
|
-
templateParser,
|
|
810
|
-
visibleInfo.startWithPadding,
|
|
811
|
-
visibleInfo.endWithPadding,
|
|
812
|
-
focusId,
|
|
813
|
-
false,
|
|
814
|
-
permanentItemList
|
|
815
|
-
);
|
|
816
|
-
dataUpdateToken.value++;
|
|
817
|
-
pageUpdater.apply();
|
|
818
|
-
_updateFocusItem();
|
|
819
|
-
onItemFocus(templateParser.IdToIndex(focusId), null);
|
|
820
|
-
if (needSlide) {
|
|
821
|
-
_slideTo(visibleInfo.start, null);
|
|
822
|
-
} else if (need_update_content) {
|
|
823
|
-
_onScroll();
|
|
824
|
-
}
|
|
825
|
-
};
|
|
826
|
-
|
|
827
|
-
const getVisibleItems = () => {
|
|
828
|
-
const info = templateParser.GetVisibleItemList(
|
|
829
|
-
visibleInfo.startWithPadding,
|
|
830
|
-
visibleInfo.endWithPadding,
|
|
831
|
-
focusId,
|
|
832
|
-
false,
|
|
833
|
-
null
|
|
834
|
-
);
|
|
835
|
-
return {
|
|
836
|
-
start: info.visibleStart,
|
|
837
|
-
end: info.visibleEnd,
|
|
838
|
-
dataList: dataList.slice(info.visibleStart, info.visibleEnd + 1),
|
|
839
|
-
};
|
|
840
|
-
};
|
|
841
|
-
|
|
842
|
-
const exportObject = {
|
|
843
|
-
lock,
|
|
844
|
-
unlock,
|
|
845
|
-
slideTo,
|
|
846
|
-
setFocusId,
|
|
847
|
-
getFocusBlockRef,
|
|
848
|
-
setEnterFocusId,
|
|
849
|
-
setEnterFocusRect,
|
|
850
|
-
slideToItem,
|
|
851
|
-
refreshData,
|
|
852
|
-
_dispatchEvent,
|
|
853
|
-
getVisibleItems,
|
|
854
|
-
};
|
|
855
|
-
|
|
856
|
-
const _calculateNearestItemByRect = (visible_range, enter_rect_info) => {
|
|
857
|
-
let edge_direction = enter_rect_info.direction;
|
|
858
|
-
let rect = enter_rect_info.rect;
|
|
859
|
-
var direction = "";
|
|
860
|
-
var point = { x: 0, y: 0 };
|
|
861
|
-
switch (edge_direction) {
|
|
862
|
-
case EdgeDirection.left:
|
|
863
|
-
direction = "left";
|
|
864
|
-
point.x = rect.x;
|
|
865
|
-
point.y = rect.y + rect.height / 4;
|
|
866
|
-
break;
|
|
867
|
-
case EdgeDirection.right:
|
|
868
|
-
direction = "right";
|
|
869
|
-
point.x = rect.x + rect.width;
|
|
870
|
-
point.y = rect.y + rect.height / 4;
|
|
871
|
-
break;
|
|
872
|
-
case EdgeDirection.top:
|
|
873
|
-
direction = "up";
|
|
874
|
-
point.x = rect.x + rect.width / 4;
|
|
875
|
-
point.y = rect.y;
|
|
876
|
-
break;
|
|
877
|
-
case EdgeDirection.bottom:
|
|
878
|
-
direction = "down";
|
|
879
|
-
point.x = rect.x + rect.width / 4;
|
|
880
|
-
point.y = rect.y + rect.height;
|
|
881
|
-
break;
|
|
882
|
-
default:
|
|
883
|
-
break;
|
|
884
|
-
}
|
|
885
|
-
|
|
886
|
-
var src_x_range = new SingleRangeModel(point.x, point.x);
|
|
887
|
-
var src_y_range = new SingleRangeModel(point.y, point.y);
|
|
888
|
-
|
|
889
|
-
var min_distance_item = null;
|
|
890
|
-
var min_distance = -1;
|
|
891
|
-
var min_direction_weighted = 0;
|
|
892
|
-
var distance = 0;
|
|
893
|
-
var direction_weighted = 0; // 根据进入方向决定的权值,用于保证
|
|
894
|
-
|
|
895
|
-
let key_pos = props.direction === VERTICAL ? "yPos" : "xPos";
|
|
896
|
-
let key_width = props.direction === VERTICAL ? "height" : "width";
|
|
897
|
-
for (let index = visible_range.start; index <= visible_range.end; index++) {
|
|
898
|
-
let item = templateParser.GetItem(index);
|
|
899
|
-
if (!item.focusable) continue;
|
|
900
|
-
let full_show =
|
|
901
|
-
item[key_pos] >= visibleInfo.start &&
|
|
902
|
-
item[key_pos] + item[key_width] - 1 <= visibleInfo.end;
|
|
903
|
-
if (full_show) {
|
|
904
|
-
let x_pos =
|
|
905
|
-
props.direction === VERTICAL
|
|
906
|
-
? item.xPos
|
|
907
|
-
: item.xPos - visibleInfo.start;
|
|
908
|
-
let y_pos =
|
|
909
|
-
props.direction === VERTICAL
|
|
910
|
-
? item.yPos - visibleInfo.start
|
|
911
|
-
: item.yPos;
|
|
912
|
-
var target_x_range = new SingleRangeModel(x_pos, x_pos + item.width - 1);
|
|
913
|
-
var target_y_range = new SingleRangeModel(y_pos, y_pos + item.height - 1);
|
|
914
|
-
switch (direction) {
|
|
915
|
-
case "left":
|
|
916
|
-
if (point.x < x_pos + item.width - 1) {
|
|
917
|
-
// 这个点在item左侧,不可能左移到item
|
|
918
|
-
continue;
|
|
919
|
-
}
|
|
920
|
-
if (point.y < y_pos) {
|
|
921
|
-
//1.该点在其上,计算point和item右上角的距离
|
|
922
|
-
distance =
|
|
923
|
-
Math.pow(point.x - (x_pos + item.width - 1), 2) +
|
|
924
|
-
Math.pow(y_pos - point.y, 2);
|
|
925
|
-
} else if (src_y_range.IsInterAct(target_y_range)) {
|
|
926
|
-
//2.该点在其中,计算point和item右边框的垂直距离
|
|
927
|
-
distance = Math.pow(point.x - (x_pos + item.width - 1), 2);
|
|
928
|
-
} else if (point.y > y_pos + item.height - 1) {
|
|
929
|
-
//3.该点在其下,计算point到item右下角的距离
|
|
930
|
-
distance =
|
|
931
|
-
Math.pow(point.x - (x_pos + item.width - 1), 2) +
|
|
932
|
-
Math.pow(point.y - (y_pos + item.height - 1), 2);
|
|
933
|
-
}
|
|
934
|
-
// point与item右边框的距离作为权值
|
|
935
|
-
direction_weighted = Math.abs(point.x - (x_pos + item.width - 1));
|
|
936
|
-
break;
|
|
937
|
-
case "right":
|
|
938
|
-
if (point.x > x_pos) {
|
|
939
|
-
// 这个点在item右侧,不可能右移到item
|
|
940
|
-
continue;
|
|
941
|
-
}
|
|
942
|
-
if (point.y < y_pos) {
|
|
943
|
-
//1.该点在其上, 计算point和item左上角的距离
|
|
944
|
-
distance =
|
|
945
|
-
Math.pow(x_pos - point.x, 2) + Math.pow(y_pos - point.y, 2);
|
|
946
|
-
} else if (src_y_range.IsInterAct(target_y_range)) {
|
|
947
|
-
//2.该点在其中,计算point和item左边框的垂直距离
|
|
948
|
-
distance = Math.pow(x_pos - point.x, 2);
|
|
949
|
-
//(x2-x1)^2
|
|
950
|
-
} else if (point.y > y_pos + item.height - 1) {
|
|
951
|
-
//3.该点在其下,计算point和item左下角的距离
|
|
952
|
-
distance =
|
|
953
|
-
Math.pow(x_pos - point.x, 2) +
|
|
954
|
-
Math.pow(point.y - (y_pos + item.height - 1), 2);
|
|
955
|
-
}
|
|
956
|
-
// point与item左边框的距离作为权值
|
|
957
|
-
direction_weighted = Math.abs(point.x - x_pos);
|
|
958
|
-
break;
|
|
959
|
-
case "up":
|
|
960
|
-
if (point.y < y_pos + item.height - 1) {
|
|
961
|
-
// 这个点在item上侧,不可能上移到item
|
|
962
|
-
continue;
|
|
963
|
-
}
|
|
964
|
-
if (point.x < x_pos) {
|
|
965
|
-
//1.该点在其前,计算point和item右下角的距离
|
|
966
|
-
distance =
|
|
967
|
-
Math.pow(point.x - x_pos, 2) +
|
|
968
|
-
Math.pow(point.y - (y_pos + item.height - 1), 2);
|
|
969
|
-
} else if (src_x_range.IsInterAct(target_x_range)) {
|
|
970
|
-
//2.该点在其中,计算point和item下边框的垂直距离
|
|
971
|
-
distance = Math.pow(point.y - (y_pos + item.height - 1), 2);
|
|
972
|
-
} else if (point.x > x_pos + item.width - 1) {
|
|
973
|
-
//3.该点在其后,计算point和item左下角的距离
|
|
974
|
-
distance =
|
|
975
|
-
Math.pow(point.x - (x_pos + item.width - 1), 2) +
|
|
976
|
-
Math.pow(point.y - (y_pos + item.height - 1), 2);
|
|
977
|
-
}
|
|
978
|
-
// point与item下边框的距离作为权值
|
|
979
|
-
direction_weighted = Math.abs(point.y - (y_pos + item.height - 1));
|
|
980
|
-
break;
|
|
981
|
-
case "down":
|
|
982
|
-
if (point.y > y_pos) {
|
|
983
|
-
// 这个点在item下侧,不可能下移到item
|
|
984
|
-
continue;
|
|
985
|
-
}
|
|
986
|
-
if (point.x < x_pos) {
|
|
987
|
-
//1.该点在其前,计算point和item右上角的距离
|
|
988
|
-
distance =
|
|
989
|
-
Math.pow(point.x - x_pos, 2) + Math.pow(y_pos - point.y, 2);
|
|
990
|
-
} else if (src_x_range.IsInterAct(target_x_range)) {
|
|
991
|
-
//2.该点在其中,计算point和item上边框的垂直距离
|
|
992
|
-
distance = Math.pow(y_pos - point.y, 2);
|
|
993
|
-
} else if (point.x > x_pos + item.width - 1) {
|
|
994
|
-
//3.该点在其后,计算point和item左上角的距离
|
|
995
|
-
distance =
|
|
996
|
-
Math.pow(point.x - (x_pos + item.width - 1), 2) +
|
|
997
|
-
Math.pow(y_pos - point.y, 2);
|
|
998
|
-
}
|
|
999
|
-
// point与item上边框的距离作为权值
|
|
1000
|
-
direction_weighted = Math.abs(point.y - y_pos);
|
|
1001
|
-
break;
|
|
1002
|
-
default:
|
|
1003
|
-
console.log("direction is error:" + direction);
|
|
1004
|
-
break;
|
|
1005
|
-
}
|
|
1006
|
-
if (min_distance < 0) {
|
|
1007
|
-
// 设置首个找到的项目
|
|
1008
|
-
min_distance = distance;
|
|
1009
|
-
min_direction_weighted = direction_weighted;
|
|
1010
|
-
min_distance_item = item;
|
|
1011
|
-
} else {
|
|
1012
|
-
if (
|
|
1013
|
-
min_direction_weighted > direction_weighted ||
|
|
1014
|
-
(min_direction_weighted === direction_weighted &&
|
|
1015
|
-
min_distance > distance)
|
|
1016
|
-
) {
|
|
1017
|
-
// 先进行权值比较,在权值相等时,再比较距离
|
|
1018
|
-
min_distance = distance;
|
|
1019
|
-
min_direction_weighted = direction_weighted;
|
|
1020
|
-
min_distance_item = item;
|
|
1021
|
-
}
|
|
1022
|
-
}
|
|
1023
|
-
}
|
|
1024
|
-
}
|
|
1025
|
-
|
|
1026
|
-
if (min_distance_item) {
|
|
1027
|
-
return min_distance_item.id;
|
|
1028
|
-
} else {
|
|
1029
|
-
return 0;
|
|
1030
|
-
}
|
|
1031
|
-
};
|
|
1032
|
-
|
|
1033
|
-
const onKeyDown = (ev) => {
|
|
1034
|
-
if (innerData.length == 0) {
|
|
1035
|
-
const edgeDirectionMap = {
|
|
1036
|
-
37: EdgeDirection.left,
|
|
1037
|
-
38: EdgeDirection.top,
|
|
1038
|
-
39: EdgeDirection.right,
|
|
1039
|
-
40: EdgeDirection.bottom,
|
|
1040
|
-
};
|
|
1041
|
-
if (typeof edgeDirectionMap[ev.keyCode] !== "undefined") {
|
|
1042
|
-
props.onEdge?.({
|
|
1043
|
-
direction: edgeDirectionMap[ev.keyCode],
|
|
1044
|
-
rect: {
|
|
1045
|
-
x: 0,
|
|
1046
|
-
y: 0,
|
|
1047
|
-
width: 0,
|
|
1048
|
-
height: 0,
|
|
1049
|
-
},
|
|
1050
|
-
});
|
|
1051
|
-
return true;
|
|
1052
|
-
}
|
|
1053
|
-
return false;
|
|
1054
|
-
}
|
|
1055
|
-
let horizontal_direction = 0;
|
|
1056
|
-
let vertical_direction = 0;
|
|
1057
|
-
switch (ev.keyCode) {
|
|
1058
|
-
case 37:
|
|
1059
|
-
horizontal_direction = -1;
|
|
1060
|
-
_moveToNext(horizontal_direction, vertical_direction);
|
|
1061
|
-
break;
|
|
1062
|
-
case 38:
|
|
1063
|
-
vertical_direction = -1;
|
|
1064
|
-
_moveToNext(horizontal_direction, vertical_direction);
|
|
1065
|
-
break;
|
|
1066
|
-
case 39:
|
|
1067
|
-
horizontal_direction = 1;
|
|
1068
|
-
_moveToNext(horizontal_direction, vertical_direction);
|
|
1069
|
-
break;
|
|
1070
|
-
case 40:
|
|
1071
|
-
vertical_direction = 1;
|
|
1072
|
-
_moveToNext(horizontal_direction, vertical_direction);
|
|
1073
|
-
break;
|
|
1074
|
-
case 13:
|
|
1075
|
-
onItemClick(templateParser.IdToIndex(focusId));
|
|
1076
|
-
break;
|
|
1077
|
-
default:
|
|
1078
|
-
//只接受上下左右确定键
|
|
1079
|
-
return false;
|
|
1080
|
-
}
|
|
1081
|
-
return true;
|
|
1082
|
-
};
|
|
1083
|
-
|
|
1084
|
-
const _slideTo = (target, animObj) => {
|
|
1085
|
-
if (props.direction === HORIZONTAL) {
|
|
1086
|
-
_updatePosition(-target, 0, animObj);
|
|
1087
|
-
} else {
|
|
1088
|
-
_updatePosition(0, -target, animObj);
|
|
1089
|
-
}
|
|
1090
|
-
};
|
|
1091
|
-
|
|
1092
|
-
const _onTemplateAdd = (item) => {
|
|
1093
|
-
let obj = {
|
|
1094
|
-
data: item,
|
|
1095
|
-
index: innerData.length,
|
|
1096
|
-
controller: reactive({
|
|
1097
|
-
zIndex: item.normalZIndex >= 0 ? item.normalZIndex : 0,
|
|
1098
|
-
}),
|
|
1099
|
-
mounted: false,
|
|
1100
|
-
itemDivRef: null,
|
|
1101
|
-
touchInited: false,
|
|
1102
|
-
refCallback(el) {
|
|
1103
|
-
if (el == null) {
|
|
1104
|
-
this.touchInited = false;
|
|
1105
|
-
this.customerCallback = {};
|
|
1106
|
-
}
|
|
1107
|
-
this.itemDivRef = el;
|
|
1108
|
-
},
|
|
1109
|
-
slotMounted: ref(false),
|
|
1110
|
-
slotDivRef(el) {
|
|
1111
|
-
if (!this.slotMounted.value && el) {
|
|
1112
|
-
this.slotMounted.value = true;
|
|
1113
|
-
if (callFocusAfterUpdate && this.data.id === focusId) {
|
|
1114
|
-
nextTick(() => {
|
|
1115
|
-
onItemFocus(templateParser.IdToIndex(focusId), preEdgeRect);
|
|
1116
|
-
});
|
|
1117
|
-
callFocusAfterUpdate = false;
|
|
1118
|
-
}
|
|
1119
|
-
} else if (!el && this.slotMounted.value) {
|
|
1120
|
-
this.slotMounted.value = false;
|
|
1121
|
-
}
|
|
1122
|
-
},
|
|
1123
|
-
customerCallback: {},
|
|
1124
|
-
register: {
|
|
1125
|
-
register(name, func) {
|
|
1126
|
-
this.customerCallback[name] = func;
|
|
1127
|
-
},
|
|
1128
|
-
unregister(name) {
|
|
1129
|
-
delete this.customerCallback[name];
|
|
1130
|
-
},
|
|
1131
|
-
},
|
|
1132
|
-
callbacks: {
|
|
1133
|
-
callable(name) {
|
|
1134
|
-
return this.slotMounted.value && this.customerCallback[name];
|
|
1135
|
-
},
|
|
1136
|
-
onFocus(preEdge) {
|
|
1137
|
-
this.customerCallback.onFocus?.(preEdge);
|
|
1138
|
-
},
|
|
1139
|
-
onBlur() {
|
|
1140
|
-
this.customerCallback.onBlur?.();
|
|
1141
|
-
},
|
|
1142
|
-
onClick() {
|
|
1143
|
-
this.customerCallback.onClick?.();
|
|
1144
|
-
},
|
|
1145
|
-
onWidgetEdge(rect) {
|
|
1146
|
-
this.customerCallback.onWidgetEdge?.(rect);
|
|
1147
|
-
},
|
|
1148
|
-
},
|
|
1149
|
-
itemConfig: props.itemConfig?.(item.data),
|
|
1150
|
-
query: {
|
|
1151
|
-
id: item.id,
|
|
1152
|
-
index: item.index,
|
|
1153
|
-
position: _getPosition,
|
|
1154
|
-
templatePosition: _getTemplatePosition,
|
|
1155
|
-
getCurrentFocusId: _getCurrentId,
|
|
1156
|
-
slideTo: slideTo,
|
|
1157
|
-
},
|
|
1158
|
-
};
|
|
1159
|
-
bindFunctions(obj, obj);
|
|
1160
|
-
innerData.push(obj);
|
|
1161
|
-
if (item.permanent) {
|
|
1162
|
-
permanentItemList.push({
|
|
1163
|
-
index: innerData.length - 1,
|
|
1164
|
-
alreadyShow: false,
|
|
1165
|
-
});
|
|
1166
|
-
}
|
|
1167
|
-
const lastItem = templateParser.GetItem(-1);
|
|
1168
|
-
if (props.direction == VERTICAL) {
|
|
1169
|
-
touchContainerH.value = lastItem.yPos + lastItem.height - 1;
|
|
1170
|
-
} else {
|
|
1171
|
-
touchContainerW.value = lastItem.xPos + lastItem.width - 1;
|
|
1172
|
-
}
|
|
1173
|
-
};
|
|
1174
|
-
|
|
1175
|
-
const _itemOnFocusSideEffect = (item, edgeRect) => {
|
|
1176
|
-
_onFocusChange(item.data.id);
|
|
1177
|
-
if (item.itemDivRef) {
|
|
1178
|
-
let event = {
|
|
1179
|
-
type: "focusRect",
|
|
1180
|
-
direction: edgeRect?.direction?.description,
|
|
1181
|
-
element: toRaw(item.itemDivRef),
|
|
1182
|
-
};
|
|
1183
|
-
_bubbleCustomerEvent(event);
|
|
1184
|
-
}
|
|
1185
|
-
};
|
|
1186
|
-
|
|
1187
|
-
const _onCustomerEvent = (ev) => {
|
|
1188
|
-
if (ev.type === "focusRect") {
|
|
1189
|
-
if (childSlideEventLock) {
|
|
1190
|
-
return true;
|
|
1191
|
-
}
|
|
1192
|
-
if (ev.ownerNode == exportObject) {
|
|
1193
|
-
return false;
|
|
1194
|
-
}
|
|
1195
|
-
let item_div = ev.element;
|
|
1196
|
-
let direction = 0;
|
|
1197
|
-
if (props.direction == HORIZONTAL) {
|
|
1198
|
-
if (ev.direction == "left") {
|
|
1199
|
-
direction = -1;
|
|
1200
|
-
} else if (ev.direction == "right") {
|
|
1201
|
-
direction = 1;
|
|
1202
|
-
}
|
|
1203
|
-
} else {
|
|
1204
|
-
if (ev.direction == "top") {
|
|
1205
|
-
direction = -1;
|
|
1206
|
-
} else if (ev.direction == "bottom") {
|
|
1207
|
-
direction = 1;
|
|
1208
|
-
}
|
|
1209
|
-
}
|
|
1210
|
-
const item_layout = item_div.jsvGetRelativePosition(toRaw(locateDiv.value));
|
|
1211
|
-
|
|
1212
|
-
let obj = {
|
|
1213
|
-
xPos: item_layout.left,
|
|
1214
|
-
yPos: item_layout.top,
|
|
1215
|
-
width: item_layout.width,
|
|
1216
|
-
height: item_layout.height,
|
|
1217
|
-
centerYPos: Math.floor(item_layout.top + item_layout.height / 2),
|
|
1218
|
-
centerXPos: Math.floor(item_layout.left + item_layout.width / 2),
|
|
1219
|
-
index: templateParser.IdToIndex(focusId),
|
|
1220
|
-
};
|
|
1221
|
-
|
|
1222
|
-
let cur_slide = _calculateVisibleStart(obj, direction);
|
|
1223
|
-
if (cur_slide != visibleInfo.start) {
|
|
1224
|
-
visibleInfo.start = cur_slide;
|
|
1225
|
-
pageUpdater.update(
|
|
1226
|
-
templateParser,
|
|
1227
|
-
visibleInfo.startWithPadding - props.keepTraceRange * pageRange,
|
|
1228
|
-
Math.min(
|
|
1229
|
-
visibleInfo.startMax +
|
|
1230
|
-
visibleInfo.range +
|
|
1231
|
-
visibleInfo.padding.end -
|
|
1232
|
-
1,
|
|
1233
|
-
visibleInfo.endWithPadding + props.keepTraceRange * pageRange
|
|
1234
|
-
),
|
|
1235
|
-
focusId,
|
|
1236
|
-
true,
|
|
1237
|
-
permanentItemList
|
|
1238
|
-
);
|
|
1239
|
-
pageUpdater.applyTmp();
|
|
1240
|
-
_slideTo(visibleInfo.start, {
|
|
1241
|
-
easing: "",
|
|
1242
|
-
onstart: null,
|
|
1243
|
-
speed: props.slideSetting.Speed,
|
|
1244
|
-
onend: _onSlideEnd,
|
|
1245
|
-
});
|
|
1246
|
-
return true;
|
|
1247
|
-
}
|
|
1248
|
-
}
|
|
1249
|
-
return false;
|
|
1250
|
-
};
|
|
1251
|
-
|
|
1252
|
-
const _bubbleCustomerEvent = (event) => {
|
|
1253
|
-
if (props.sendFocusRectEvent && event) {
|
|
1254
|
-
event.ownerNode = exportObject;
|
|
1255
|
-
toRaw(focusNode.value)?.bubbleCustomerEvent(event);
|
|
1256
|
-
}
|
|
1257
|
-
};
|
|
1258
|
-
|
|
1259
|
-
const _moveToNext = (
|
|
1260
|
-
horizontal_direction,
|
|
1261
|
-
vertical_direction,
|
|
1262
|
-
item_edge_rect
|
|
1263
|
-
) => {
|
|
1264
|
-
let cur_focus_item = templateParser.GetItemById(focusId);
|
|
1265
|
-
let next_focus_item = templateParser.GetNextItem(
|
|
1266
|
-
focusId,
|
|
1267
|
-
vertical_direction,
|
|
1268
|
-
horizontal_direction,
|
|
1269
|
-
props.focusMoveType
|
|
1270
|
-
);
|
|
1271
|
-
if (next_focus_item !== null) {
|
|
1272
|
-
preFocusId = focusId;
|
|
1273
|
-
templateItemAdder.tryAddItem(next_focus_item, 1);
|
|
1274
|
-
focusId = next_focus_item.id;
|
|
1275
|
-
|
|
1276
|
-
let direction =
|
|
1277
|
-
props.direction === VERTICAL ? vertical_direction : horizontal_direction;
|
|
1278
|
-
|
|
1279
|
-
let cur_visible_start = _calculateVisibleStart(next_focus_item, direction);
|
|
1280
|
-
if (
|
|
1281
|
-
!innerData[templateParser.IdToIndex(focusId)].itemConfig?.takeOverSlide &&
|
|
1282
|
-
visibleInfo.start !== cur_visible_start
|
|
1283
|
-
) {
|
|
1284
|
-
if (next_focus_item.doSlide) {
|
|
1285
|
-
visibleInfo.start = cur_visible_start;
|
|
1286
|
-
let animObj = {
|
|
1287
|
-
easing: "",
|
|
1288
|
-
onstart: null,
|
|
1289
|
-
speed: props.slideSetting.Speed,
|
|
1290
|
-
onend: _onSlideEnd,
|
|
1291
|
-
};
|
|
1292
|
-
_slideTo(visibleInfo.start, animObj);
|
|
1293
|
-
pageUpdater.update(
|
|
1294
|
-
templateParser,
|
|
1295
|
-
visibleInfo.startWithPadding - props.keepTraceRange * pageRange,
|
|
1296
|
-
Math.min(
|
|
1297
|
-
visibleInfo.startMax +
|
|
1298
|
-
visibleInfo.range +
|
|
1299
|
-
visibleInfo.padding.end -
|
|
1300
|
-
1,
|
|
1301
|
-
visibleInfo.endWithPadding + props.keepTraceRange * pageRange
|
|
1302
|
-
),
|
|
1303
|
-
next_focus_item.id,
|
|
1304
|
-
false,
|
|
1305
|
-
permanentItemList
|
|
1306
|
-
);
|
|
1307
|
-
} else {
|
|
1308
|
-
//不做滚动时,保证获焦的item创建
|
|
1309
|
-
pageUpdater.update(
|
|
1310
|
-
templateParser,
|
|
1311
|
-
cur_visible_start,
|
|
1312
|
-
cur_visible_start + visibleInfo.range + visibleInfo.padding.end - 1,
|
|
1313
|
-
next_focus_item.id,
|
|
1314
|
-
false,
|
|
1315
|
-
permanentItemList
|
|
1316
|
-
);
|
|
1317
|
-
}
|
|
1318
|
-
pageUpdater.applyTmp();
|
|
1319
|
-
}
|
|
1320
|
-
|
|
1321
|
-
let rect;
|
|
1322
|
-
let x_off_set = cur_focus_item.xPos - next_focus_item.xPos;
|
|
1323
|
-
let y_off_set = cur_focus_item.yPos - next_focus_item.yPos;
|
|
1324
|
-
if (item_edge_rect && item_edge_rect.rect) {
|
|
1325
|
-
item_edge_rect.rect.x += x_off_set;
|
|
1326
|
-
item_edge_rect.rect.y += y_off_set;
|
|
1327
|
-
rect = item_edge_rect;
|
|
1328
|
-
} else {
|
|
1329
|
-
let direction;
|
|
1330
|
-
if (horizontal_direction > 0) {
|
|
1331
|
-
direction = EdgeDirection.right;
|
|
1332
|
-
} else if (horizontal_direction < 0) {
|
|
1333
|
-
direction = EdgeDirection.left;
|
|
1334
|
-
} else if (vertical_direction > 0) {
|
|
1335
|
-
direction = EdgeDirection.bottom;
|
|
1336
|
-
} else if (vertical_direction < 0) {
|
|
1337
|
-
direction = EdgeDirection.top;
|
|
1338
|
-
}
|
|
1339
|
-
rect = {
|
|
1340
|
-
direction,
|
|
1341
|
-
rect: {
|
|
1342
|
-
x: x_off_set,
|
|
1343
|
-
y: y_off_set,
|
|
1344
|
-
width: cur_focus_item.width,
|
|
1345
|
-
height: cur_focus_item.height,
|
|
1346
|
-
},
|
|
1347
|
-
};
|
|
1348
|
-
}
|
|
1349
|
-
preEdgeRect = rect;
|
|
1350
|
-
_updateBlurItem();
|
|
1351
|
-
_updateFocusItem();
|
|
1352
|
-
onItemBlur(templateParser.IdToIndex(preFocusId));
|
|
1353
|
-
onItemFocus(templateParser.IdToIndex(focusId), preEdgeRect);
|
|
1354
|
-
} else {
|
|
1355
|
-
let x_off_set = props.direction === VERTICAL ? 0 : visibleInfo.start;
|
|
1356
|
-
let y_off_set = props.direction === VERTICAL ? visibleInfo.start : 0;
|
|
1357
|
-
let edge;
|
|
1358
|
-
if (horizontal_direction === 1) {
|
|
1359
|
-
edge = EdgeDirection.right;
|
|
1360
|
-
}
|
|
1361
|
-
if (horizontal_direction === -1) {
|
|
1362
|
-
edge = EdgeDirection.left;
|
|
1363
|
-
}
|
|
1364
|
-
if (vertical_direction === 1) {
|
|
1365
|
-
edge = EdgeDirection.bottom;
|
|
1366
|
-
}
|
|
1367
|
-
if (vertical_direction === -1) {
|
|
1368
|
-
edge = EdgeDirection.top;
|
|
1369
|
-
}
|
|
1370
|
-
let rect = {
|
|
1371
|
-
x: cur_focus_item.xPos - x_off_set,
|
|
1372
|
-
y: cur_focus_item.yPos - y_off_set,
|
|
1373
|
-
width: cur_focus_item.width,
|
|
1374
|
-
height: cur_focus_item.height,
|
|
1375
|
-
};
|
|
1376
|
-
props.onEdge?.({ direction: edge, rect: rect });
|
|
1377
|
-
innerData[templateParser.IdToIndex(focusId)].callbacks.onWidgetEdge?.({
|
|
1378
|
-
direction: edge,
|
|
1379
|
-
});
|
|
1380
|
-
}
|
|
1381
|
-
};
|
|
1382
|
-
|
|
1383
|
-
const _calculateVisibleStart = (target_item, direction) => {
|
|
1384
|
-
if (!target_item) {
|
|
1385
|
-
console.error("MetroWidget: _calculateVisibleStart target item is null");
|
|
1386
|
-
return 0;
|
|
1387
|
-
}
|
|
1388
|
-
preAnchorItemIndex = target_item.index;
|
|
1389
|
-
let pos_key = directionFreeKeyMap.pos[vertical];
|
|
1390
|
-
let size_key = directionFreeKeyMap.size[vertical];
|
|
1391
|
-
let center_key = directionFreeKeyMap.center[vertical];
|
|
1392
|
-
let new_visible_start = visibleInfo.start;
|
|
1393
|
-
|
|
1394
|
-
switch (props.slideSetting.Type) {
|
|
1395
|
-
case SlideSetting.Type.FIX_POSITION:
|
|
1396
|
-
//FIX_POSITION 模式会将当前 item 的中心固定到指定位置
|
|
1397
|
-
new_visible_start = Math.ceil(
|
|
1398
|
-
target_item[center_key] -
|
|
1399
|
-
visibleInfo.range * props.slideSetting.FixPercent
|
|
1400
|
-
);
|
|
1401
|
-
break;
|
|
1402
|
-
case SlideSetting.Type.WHOLE_PAGE:
|
|
1403
|
-
if (typeof target_item.pageHeadIndex == "undefined") {
|
|
1404
|
-
//TODO 子控制滚动时whole page滚动
|
|
1405
|
-
console.error(
|
|
1406
|
-
"child controlled whole page slide type is not supported."
|
|
1407
|
-
);
|
|
1408
|
-
} else {
|
|
1409
|
-
new_visible_start = templateParser.GetItem(target_item.pageHeadIndex)[
|
|
1410
|
-
pos_key
|
|
1411
|
-
];
|
|
1412
|
-
}
|
|
1413
|
-
|
|
1414
|
-
break;
|
|
1415
|
-
case SlideSetting.Type.SEAMLESS:
|
|
1416
|
-
if (
|
|
1417
|
-
target_item[size_key] >=
|
|
1418
|
-
visibleInfo.range *
|
|
1419
|
-
(props.slideSetting.EndPercent - props.slideSetting.StartPercent)
|
|
1420
|
-
) {
|
|
1421
|
-
//尺寸较大的item
|
|
1422
|
-
new_visible_start = target_item[center_key] - visibleInfo.range * 0.5;
|
|
1423
|
-
} else {
|
|
1424
|
-
if (direction > 0) {
|
|
1425
|
-
if (
|
|
1426
|
-
target_item[pos_key] + target_item[size_key] >
|
|
1427
|
-
visibleInfo.start +
|
|
1428
|
-
visibleInfo.range * props.slideSetting.EndPercent
|
|
1429
|
-
) {
|
|
1430
|
-
new_visible_start =
|
|
1431
|
-
target_item[pos_key] +
|
|
1432
|
-
target_item[size_key] -
|
|
1433
|
-
visibleInfo.range * props.slideSetting.EndPercent;
|
|
1434
|
-
}
|
|
1435
|
-
} else if (direction < 0) {
|
|
1436
|
-
if (
|
|
1437
|
-
target_item[pos_key] <
|
|
1438
|
-
visibleInfo.start +
|
|
1439
|
-
visibleInfo.range * props.slideSetting.StartPercent
|
|
1440
|
-
) {
|
|
1441
|
-
new_visible_start =
|
|
1442
|
-
target_item[pos_key] -
|
|
1443
|
-
visibleInfo.range * props.slideSetting.StartPercent;
|
|
1444
|
-
}
|
|
1445
|
-
} else {
|
|
1446
|
-
//不是沿widget方向的移动
|
|
1447
|
-
if (target_item[pos_key] < visibleInfo.start) {
|
|
1448
|
-
new_visible_start =
|
|
1449
|
-
target_item[pos_key] -
|
|
1450
|
-
visibleInfo.range * props.slideSetting.StartPercent;
|
|
1451
|
-
} else if (
|
|
1452
|
-
target_item[pos_key] + target_item[size_key] >
|
|
1453
|
-
visibleInfo.end
|
|
1454
|
-
) {
|
|
1455
|
-
new_visible_start =
|
|
1456
|
-
target_item[pos_key] +
|
|
1457
|
-
target_item[size_key] -
|
|
1458
|
-
visibleInfo.range * props.slideSetting.EndPercent;
|
|
1459
|
-
}
|
|
1460
|
-
}
|
|
1461
|
-
}
|
|
1462
|
-
break;
|
|
1463
|
-
default:
|
|
1464
|
-
console.error(
|
|
1465
|
-
"MetroWidget: undefined slide type",
|
|
1466
|
-
props.slideSetting.Type
|
|
1467
|
-
);
|
|
1468
|
-
}
|
|
1469
|
-
|
|
1470
|
-
if ((props.slideSetting.BoundaryProtect & SlideSetting.START_PROTECT) > 0) {
|
|
1471
|
-
let boundary = 0;
|
|
1472
|
-
//首个元素是占位符时, 在保证获焦区域完全展示的前提下要保证首个不可获焦元素的完全展示
|
|
1473
|
-
if (
|
|
1474
|
-
!templateParser.GetItem(0).focusable &&
|
|
1475
|
-
target_item[pos_key] + target_item[size_key] <= visibleInfo.range
|
|
1476
|
-
) {
|
|
1477
|
-
boundary = templateParser.GetItem(0)[size_key];
|
|
1478
|
-
}
|
|
1479
|
-
new_visible_start = new_visible_start < boundary ? 0 : new_visible_start;
|
|
1480
|
-
}
|
|
1481
|
-
if ((props.slideSetting.BoundaryProtect & SlideSetting.END_PROTECT) > 0) {
|
|
1482
|
-
let last_item = templateParser.GetItem(-1);
|
|
1483
|
-
let last_visible_start =
|
|
1484
|
-
last_item[pos_key] + last_item[size_key] - visibleInfo.range;
|
|
1485
|
-
last_visible_start = last_visible_start < 0 ? 0 : last_visible_start;
|
|
1486
|
-
let boundary = last_visible_start;
|
|
1487
|
-
if (
|
|
1488
|
-
!last_item.focusable &&
|
|
1489
|
-
target_item[pos_key] - last_visible_start >= 0
|
|
1490
|
-
) {
|
|
1491
|
-
//最后元素是占位符, 在保证获焦区域完全展示的前提下要保证不可获焦元素的完全展示
|
|
1492
|
-
boundary = last_item[pos_key] - visibleInfo.range;
|
|
1493
|
-
}
|
|
1494
|
-
new_visible_start =
|
|
1495
|
-
new_visible_start > boundary ? last_visible_start : new_visible_start;
|
|
1496
|
-
}
|
|
1497
|
-
return Math.round(new_visible_start);
|
|
1498
|
-
};
|
|
1499
|
-
|
|
1500
|
-
const _onFocusableItemEdge = (edge_info) => {
|
|
1501
|
-
let horizontal_direction = 0;
|
|
1502
|
-
let vertical_direction = 0;
|
|
1503
|
-
switch (edge_info.direction) {
|
|
1504
|
-
case EdgeDirection.left:
|
|
1505
|
-
horizontal_direction = -1;
|
|
1506
|
-
break;
|
|
1507
|
-
case EdgeDirection.right:
|
|
1508
|
-
horizontal_direction = 1;
|
|
1509
|
-
break;
|
|
1510
|
-
case EdgeDirection.top:
|
|
1511
|
-
vertical_direction = -1;
|
|
1512
|
-
break;
|
|
1513
|
-
case EdgeDirection.bottom:
|
|
1514
|
-
vertical_direction = 1;
|
|
1515
|
-
break;
|
|
1516
|
-
default:
|
|
1517
|
-
break;
|
|
1518
|
-
}
|
|
1519
|
-
_moveToNext(horizontal_direction, vertical_direction, edge_info);
|
|
1520
|
-
};
|
|
1521
|
-
|
|
1522
|
-
const _ifValidEnterRect = (rect_info) => {
|
|
1523
|
-
return rect_info && rect_info.direction && rect_info.rect;
|
|
1524
|
-
};
|
|
1525
|
-
|
|
1526
|
-
const _setZIndex = (index, z_index, is_focus) => {
|
|
1527
|
-
if (innerData[index]) {
|
|
1528
|
-
let data = innerData[index].data,
|
|
1529
|
-
i = z_index;
|
|
1530
|
-
if (is_focus && data.focusZIndex >= 0) {
|
|
1531
|
-
i = data.focusZIndex;
|
|
1532
|
-
} else if (data.normalZIndex >= 0) {
|
|
1533
|
-
i = data.normalZIndex;
|
|
1534
|
-
}
|
|
1535
|
-
innerData[index].controller.zIndex = i;
|
|
1536
|
-
}
|
|
1537
|
-
};
|
|
1538
|
-
|
|
1539
|
-
const _onFocus = (params) => {
|
|
1540
|
-
isFocus = true;
|
|
1541
|
-
preFocusId = -1;
|
|
1542
|
-
if (innerData.length === 0) {
|
|
1543
|
-
console.warn(`MetroWidget: ${props.name} get focus while data is empty.`);
|
|
1544
|
-
return;
|
|
1545
|
-
}
|
|
1546
|
-
let focus_id =
|
|
1547
|
-
typeof enterFocusId !== "undefined" &&
|
|
1548
|
-
enterFocusId >= 0 &&
|
|
1549
|
-
enterFocusId < templateParser.GetTemplate().List.length
|
|
1550
|
-
? enterFocusId
|
|
1551
|
-
: focusId;
|
|
1552
|
-
focus_id = _ifValidEnterRect(enterFocusRect)
|
|
1553
|
-
? _calculateNearestItemByRect(pageUpdater.getRange(), enterFocusRect)
|
|
1554
|
-
: focus_id;
|
|
1555
|
-
|
|
1556
|
-
preEdgeRect = enterFocusRect;
|
|
1557
|
-
focusId = focus_id;
|
|
1558
|
-
enterFocusId = -1;
|
|
1559
|
-
enterFocusRect = null;
|
|
1560
|
-
_updateFocusItem();
|
|
1561
|
-
onItemFocus(templateParser.IdToIndex(focusId), preEdgeRect);
|
|
1562
|
-
props.onFocus?.();
|
|
1563
|
-
};
|
|
1564
|
-
|
|
1565
|
-
const _onBlur = () => {
|
|
1566
|
-
isFocus = false;
|
|
1567
|
-
enterFocusId = -1;
|
|
1568
|
-
enterFocusRect = null;
|
|
1569
|
-
preEdgeRect = null;
|
|
1570
|
-
if (innerData.length === 0) {
|
|
1571
|
-
return;
|
|
1572
|
-
}
|
|
1573
|
-
preFocusId = focusId;
|
|
1574
|
-
_updateBlurItem();
|
|
1575
|
-
innerData[templateParser.IdToIndex(preFocusId)].callbacks.onBlur();
|
|
1576
|
-
|
|
1577
|
-
props.onBlur?.();
|
|
1578
|
-
};
|
|
1579
|
-
|
|
1580
|
-
const _onSlideEnd = (event) => {
|
|
1581
|
-
if (event && event.stopPropagation) {
|
|
1582
|
-
event.stopPropagation();
|
|
1583
|
-
}
|
|
1584
|
-
pageUpdater.apply();
|
|
1585
|
-
};
|
|
1586
|
-
|
|
1587
|
-
const _updateFocusItem = () => {
|
|
1588
|
-
_setZIndex(templateParser.IdToIndex(focusId), innerData.length, true);
|
|
1589
|
-
};
|
|
1590
|
-
|
|
1591
|
-
const _updateBlurItem = () => {
|
|
1592
|
-
_setZIndex(templateParser.IdToIndex(preFocusId), 0, false);
|
|
1593
|
-
};
|
|
1594
|
-
|
|
1595
|
-
const _updateFocusByDragInfo = (viewX, viewY) => {
|
|
1596
|
-
let enterFocusRect = null;
|
|
1597
|
-
//模拟最小区域作为输入区域
|
|
1598
|
-
if (props.direction === VERTICAL) {
|
|
1599
|
-
enterFocusRect = {
|
|
1600
|
-
direction: EdgeDirection.top,
|
|
1601
|
-
rect: {
|
|
1602
|
-
x: props.left - viewX,
|
|
1603
|
-
y: props.top - viewY,
|
|
1604
|
-
width: 10,
|
|
1605
|
-
height: 10,
|
|
1606
|
-
},
|
|
1607
|
-
};
|
|
1608
|
-
} else {
|
|
1609
|
-
enterFocusRect = {
|
|
1610
|
-
direction: EdgeDirection.left,
|
|
1611
|
-
rect: {
|
|
1612
|
-
x: props.left - viewX,
|
|
1613
|
-
y: props.top - viewY,
|
|
1614
|
-
width: 10,
|
|
1615
|
-
height: 10,
|
|
1616
|
-
},
|
|
1617
|
-
};
|
|
1618
|
-
}
|
|
1619
|
-
focusId = _calculateNearestItemByRect(pageUpdater.getRange(), enterFocusRect);
|
|
1620
|
-
};
|
|
1621
|
-
|
|
1622
|
-
const _onDragUpdateItem = (visible_start, visible_end) => {
|
|
1623
|
-
templateItemAdder.tryAddItemByPosition(visible_end);
|
|
1624
|
-
pageUpdater.update(
|
|
1625
|
-
templateParser,
|
|
1626
|
-
visible_start,
|
|
1627
|
-
visible_end,
|
|
1628
|
-
0,
|
|
1629
|
-
false,
|
|
1630
|
-
permanentItemList
|
|
1631
|
-
);
|
|
1632
|
-
pageUpdater.apply();
|
|
1633
|
-
|
|
1634
|
-
Forge.sRenderBridge.InstantPerformSwap();
|
|
1635
|
-
};
|
|
1636
|
-
|
|
1637
|
-
const _getTouchListener = () => {
|
|
1638
|
-
if (!props.enableTouch) {
|
|
1639
|
-
return null;
|
|
1640
|
-
}
|
|
1641
|
-
let callback = {
|
|
1642
|
-
OnDragStart: (msg) => {
|
|
1643
|
-
if (mounted) {
|
|
1644
|
-
Promise.resolve().then(() => {
|
|
1645
|
-
let cur_visible_start = visibleInfo.start - pageRange * 2;
|
|
1646
|
-
let cur_visible_end = visibleInfo.start + pageRange * 3 - 1;
|
|
1647
|
-
preUpdateVisibleStart = cur_visible_start;
|
|
1648
|
-
_onDragUpdateItem(cur_visible_start, cur_visible_end);
|
|
1649
|
-
});
|
|
1650
|
-
}
|
|
1651
|
-
return true;
|
|
1652
|
-
},
|
|
1653
|
-
OnMoved: (msg) => {
|
|
1654
|
-
if (mounted) {
|
|
1655
|
-
Promise.resolve().then(() => {
|
|
1656
|
-
if (
|
|
1657
|
-
typeof msg.viewY != "undefined" &&
|
|
1658
|
-
typeof msg.viewX != "undefined"
|
|
1659
|
-
) {
|
|
1660
|
-
if (props.direction === VERTICAL) {
|
|
1661
|
-
visibleInfo.start = -msg.viewY;
|
|
1662
|
-
} else {
|
|
1663
|
-
visibleInfo.start = -msg.viewX;
|
|
1664
|
-
}
|
|
1665
|
-
if (visibleInfo.start < 0) {
|
|
1666
|
-
visibleInfo.start = 0;
|
|
1667
|
-
}
|
|
1668
|
-
}
|
|
1669
|
-
if (
|
|
1670
|
-
Math.abs(visibleInfo.start - preUpdateVisibleStart) <= pageRange
|
|
1671
|
-
) {
|
|
1672
|
-
let cur_visible_start = visibleInfo.start - pageRange * 2;
|
|
1673
|
-
let cur_visible_end = visibleInfo.start + pageRange * 3 - 1;
|
|
1674
|
-
preUpdateVisibleStart = cur_visible_start;
|
|
1675
|
-
_onDragUpdateItem(cur_visible_start, cur_visible_end);
|
|
1676
|
-
}
|
|
1677
|
-
});
|
|
1678
|
-
}
|
|
1679
|
-
|
|
1680
|
-
return true;
|
|
1681
|
-
},
|
|
1682
|
-
OnDragEnd: (msg) => {
|
|
1683
|
-
_updatePosition(msg["viewX"], msg["viewY"], null);
|
|
1684
|
-
preUpdateVisibleStart = visibleInfo.start;
|
|
1685
|
-
_onDragUpdateItem(
|
|
1686
|
-
visibleInfo.startWithPadding,
|
|
1687
|
-
visibleInfo.endWithPadding
|
|
1688
|
-
);
|
|
1689
|
-
_updateFocusByDragInfo(msg["viewX"], msg["viewY"]);
|
|
1690
|
-
return true;
|
|
1691
|
-
},
|
|
1692
|
-
OnFling: (msg) => {
|
|
1693
|
-
_updatePosition(msg["viewX"], msg["viewY"], null);
|
|
1694
|
-
preUpdateVisibleStart = visibleInfo.start;
|
|
1695
|
-
_onDragUpdateItem(
|
|
1696
|
-
visibleInfo.startWithPadding,
|
|
1697
|
-
visibleInfo.endWithPadding
|
|
1698
|
-
);
|
|
1699
|
-
_updateFocusByDragInfo(msg["viewX"], msg["viewY"]);
|
|
1700
|
-
return true;
|
|
1701
|
-
},
|
|
1702
|
-
OnRelease: (msg) => {
|
|
1703
|
-
return true;
|
|
1704
|
-
},
|
|
1705
|
-
};
|
|
1706
|
-
return callback;
|
|
1707
|
-
};
|
|
1708
|
-
|
|
1709
|
-
const _updatePage = (range_list) => {
|
|
1710
|
-
let list = [];
|
|
1711
|
-
for (let range of range_list) {
|
|
1712
|
-
list = list.concat(innerData.slice(range.start, range.end + 1));
|
|
1713
|
-
}
|
|
1714
|
-
renderData.value = list;
|
|
1715
|
-
if (props.enableItemRenderBreak) {
|
|
1716
|
-
itemRender.value = false;
|
|
1717
|
-
nextTick(() => {
|
|
1718
|
-
itemRender.value = true;
|
|
1719
|
-
});
|
|
1720
|
-
}
|
|
1721
|
-
};
|
|
1722
|
-
|
|
1723
|
-
const _onScroll = () => {
|
|
1724
|
-
if (props.onScroll) {
|
|
1725
|
-
const lastItem = templateParser.GetItem(-1);
|
|
1726
|
-
let totalWidth;
|
|
1727
|
-
if (vertical) {
|
|
1728
|
-
totalWidth = lastItem.yPos + lastItem.height - 1;
|
|
1729
|
-
} else {
|
|
1730
|
-
totalWidth = lastItem.xPos + lastItem.width - 1;
|
|
1731
|
-
}
|
|
1732
|
-
props.onScroll(visibleInfo.start, visibleInfo.range, totalWidth);
|
|
1733
|
-
}
|
|
1734
|
-
};
|
|
1735
|
-
|
|
1736
|
-
//之前rootview相关的代码
|
|
1737
|
-
const _updatePosition = (x, y, anim_info) => {
|
|
1738
|
-
if (slideLock) return;
|
|
1739
|
-
if (toRaw(slideDiv.value)) {
|
|
1740
|
-
let pre_left = slideDivLeft.value,
|
|
1741
|
-
pre_top = slideDivTop.value;
|
|
1742
|
-
//jsvMaskView的位置更新时会被设置位0,因此不能通过ResetLayoutParams设置位置
|
|
1743
|
-
slideDivLeft.value = x;
|
|
1744
|
-
slideDivTop.value = y;
|
|
1745
|
-
if (anim_info) {
|
|
1746
|
-
let delta_x = Math.abs(pre_left - x);
|
|
1747
|
-
let delta_y = Math.abs(pre_top - y);
|
|
1748
|
-
let duration = Math.round(
|
|
1749
|
-
delta_x === 0 ? delta_y / anim_info.speed : delta_x / anim_info.speed
|
|
1750
|
-
);
|
|
1751
|
-
let slide_animation = new Forge.TranslateAnimation(
|
|
1752
|
-
pre_left - x,
|
|
1753
|
-
0,
|
|
1754
|
-
pre_top - y,
|
|
1755
|
-
0,
|
|
1756
|
-
duration,
|
|
1757
|
-
anim_info.easing
|
|
1758
|
-
);
|
|
1759
|
-
slide_animation.SetAnimationListener(
|
|
1760
|
-
new Forge.AnimationListener(anim_info.onstart, anim_info.onend, null)
|
|
1761
|
-
);
|
|
1762
|
-
toRaw(slideDiv.value)
|
|
1763
|
-
.jsvGetProxyView(true)
|
|
1764
|
-
.StartAnimation(slide_animation);
|
|
1765
|
-
}
|
|
1766
|
-
_onScroll();
|
|
1767
|
-
}
|
|
1768
|
-
};
|
|
1769
|
-
|
|
1770
|
-
const _initRootTouch = () => {
|
|
1771
|
-
if (props.enableTouch && toRaw(slideDiv.value)) {
|
|
1772
|
-
let view = toRaw(slideDiv.value).jsvGetProxyView(true);
|
|
1773
|
-
var drag_setting = new Forge.DragSetting(
|
|
1774
|
-
dragDirection,
|
|
1775
|
-
20,
|
|
1776
|
-
false,
|
|
1777
|
-
slidePile,
|
|
1778
|
-
props.flingPageWidth,
|
|
1779
|
-
props.flingPageEdge
|
|
1780
|
-
);
|
|
1781
|
-
view.EnableDrag(drag_setting, touchListener, "translateMat(dx,dy,0)");
|
|
1782
|
-
}
|
|
1783
|
-
};
|
|
1784
|
-
|
|
1785
|
-
const _initItemViewTouch = (itemDivRef, index) => {
|
|
1786
|
-
if (props.enableTouch) {
|
|
1787
|
-
if (itemDivRef) {
|
|
1788
|
-
// 为view添加触控处理
|
|
1789
|
-
let view = itemDivRef.jsvGetProxyView(true);
|
|
1790
|
-
let dragSetting = new Forge.DragSetting(
|
|
1791
|
-
Forge.DragSetting.DIRECTION_DISABLE,
|
|
1792
|
-
20,
|
|
1793
|
-
false,
|
|
1794
|
-
new Forge.RectArea(0, 0, 0, 0),
|
|
1795
|
-
-1,
|
|
1796
|
-
3 / 4
|
|
1797
|
-
);
|
|
1798
|
-
let callback = {
|
|
1799
|
-
OnTap: (msg) => {
|
|
1800
|
-
return onItemClick(index);
|
|
1801
|
-
},
|
|
1802
|
-
};
|
|
1803
|
-
view.EnableDrag(dragSetting, callback, "translateMat(dx,dy,0)");
|
|
1804
|
-
}
|
|
1805
|
-
}
|
|
1806
|
-
};
|
|
1807
|
-
|
|
1808
|
-
//init
|
|
1809
|
-
pageUpdater = new PageUpdater(_updatePage);
|
|
1810
|
-
if (props.dispatcher) {
|
|
1811
|
-
props.dispatcher.registerComponent(exportObject);
|
|
1812
|
-
}
|
|
1813
|
-
innerPadding = _getPadding(props.padding);
|
|
1814
|
-
dragDirection = vertical
|
|
1815
|
-
? Forge.DragSetting.DIRECTION_VERTICAL
|
|
1816
|
-
: Forge.DragSetting.DIRECTION_HORIZONTAL;
|
|
1817
|
-
visibleInfo.range = vertical
|
|
1818
|
-
? props.height - innerPadding.top - innerPadding.bottom
|
|
1819
|
-
: props.width - innerPadding.left - innerPadding.right;
|
|
1820
|
-
visibleInfo.padding = vertical
|
|
1821
|
-
? { start: innerPadding.top, end: innerPadding.bottom }
|
|
1822
|
-
: { start: innerPadding.left, end: innerPadding.right };
|
|
1823
|
-
|
|
1824
|
-
if (props.provideData) {
|
|
1825
|
-
dataList = toRaw(props.provideData());
|
|
1826
|
-
} else if (props.data) {
|
|
1827
|
-
dataList = toRaw(props.data);
|
|
1828
|
-
}
|
|
1829
|
-
|
|
1830
|
-
templateParser = _getTemplateParser(
|
|
1831
|
-
props.width,
|
|
1832
|
-
props.height,
|
|
1833
|
-
props.direction,
|
|
1834
|
-
props.padding,
|
|
1835
|
-
props.supportHistoryPath,
|
|
1836
|
-
props.layoutType
|
|
1837
|
-
);
|
|
1838
|
-
|
|
1839
|
-
templateItemAdder = new TemplateItemAdder(
|
|
1840
|
-
templateParser,
|
|
1841
|
-
dataList,
|
|
1842
|
-
props.measures,
|
|
1843
|
-
pageRange,
|
|
1844
|
-
_onTemplateAdd,
|
|
1845
|
-
props.name
|
|
347
|
+
const renderBreakKey = props.enableItemRenderBreak ? RENDER_ITEM_BREAK_KEY : "";
|
|
348
|
+
const touchContainerW = ref(0);
|
|
349
|
+
const touchContainerH = ref(0);
|
|
350
|
+
const itemRender = ref(!props.enableItemRenderBreak);
|
|
351
|
+
const locateDiv = shallowRef(null);
|
|
352
|
+
const renderData = shallowRef([]);
|
|
353
|
+
const slideDiv = shallowRef(null);
|
|
354
|
+
const slideDivLeft = ref(0);
|
|
355
|
+
const slideDivTop = ref(0);
|
|
356
|
+
const itemResizeSlideDiv = shallowRef(null);
|
|
357
|
+
const itemResizeSlideLeft = ref(0);
|
|
358
|
+
const itemResizeSlideTop = ref(0);
|
|
359
|
+
const focusNode = shallowRef(null);
|
|
360
|
+
const pageUpdateToken = ref(0);
|
|
361
|
+
|
|
362
|
+
const {
|
|
363
|
+
widgetRectInfo,
|
|
364
|
+
focusBlockOnFocus,
|
|
365
|
+
focusBlockOnBlur,
|
|
366
|
+
focusBlockOnKeyDown,
|
|
367
|
+
focusBlockOnCustomerEvent,
|
|
368
|
+
_onFocusableItemEdge,
|
|
369
|
+
exportObject,
|
|
370
|
+
} = setup(
|
|
371
|
+
props,
|
|
372
|
+
touchContainerW,
|
|
373
|
+
touchContainerH,
|
|
374
|
+
itemRender,
|
|
375
|
+
locateDiv,
|
|
376
|
+
renderData,
|
|
377
|
+
slideDiv,
|
|
378
|
+
slideDivLeft,
|
|
379
|
+
slideDivTop,
|
|
380
|
+
itemResizeSlideDiv,
|
|
381
|
+
itemResizeSlideLeft,
|
|
382
|
+
itemResizeSlideTop,
|
|
383
|
+
focusNode,
|
|
384
|
+
pageUpdateToken,
|
|
385
|
+
"common"
|
|
1846
386
|
);
|
|
1847
|
-
if (props.onScroll) {
|
|
1848
|
-
templateItemAdder.tryAddItemByIndex(dataList.length - 1);
|
|
1849
|
-
} else {
|
|
1850
|
-
templateItemAdder.tryAddItem(null, 2);
|
|
1851
|
-
}
|
|
1852
|
-
|
|
1853
|
-
let template_list = templateParser.GetTemplate().List;
|
|
1854
|
-
|
|
1855
|
-
//触控相关
|
|
1856
|
-
let last_item = template_list[template_list.length - 1];
|
|
1857
|
-
if (last_item) {
|
|
1858
|
-
touchListener = _getTouchListener();
|
|
1859
|
-
touchContainerW.value =
|
|
1860
|
-
props.direction === VERTICAL
|
|
1861
|
-
? props.width
|
|
1862
|
-
: last_item.xPos + last_item.width;
|
|
1863
|
-
touchContainerH.value =
|
|
1864
|
-
props.direction === VERTICAL
|
|
1865
|
-
? last_item.yPos + last_item.height
|
|
1866
|
-
: props.height;
|
|
1867
|
-
}
|
|
1868
|
-
slidePile = new Forge.RectArea(
|
|
1869
|
-
0,
|
|
1870
|
-
0,
|
|
1871
|
-
props.width - innerPadding.left - innerPadding.right,
|
|
1872
|
-
props.height - innerPadding.top - innerPadding.bottom
|
|
1873
|
-
);
|
|
1874
|
-
let init_focus_id = 0;
|
|
1875
|
-
let cur_visible_start = 0;
|
|
1876
|
-
|
|
1877
|
-
if (typeof props.initFocusId == "number") {
|
|
1878
|
-
templateItemAdder.tryAddItemById(props.initFocusId);
|
|
1879
|
-
const item = templateParser.GetItemById(props.initFocusId);
|
|
1880
|
-
if (item) {
|
|
1881
|
-
init_focus_id = props.initFocusId;
|
|
1882
|
-
if (item.doSlide) {
|
|
1883
|
-
cur_visible_start = _calculateVisibleStart(item, 1);
|
|
1884
|
-
}
|
|
1885
|
-
}
|
|
1886
|
-
}
|
|
1887
|
-
focusId = init_focus_id;
|
|
1888
|
-
visibleInfo.start = cur_visible_start;
|
|
1889
|
-
|
|
1890
|
-
pageUpdater.update(
|
|
1891
|
-
templateParser,
|
|
1892
|
-
visibleInfo.startWithPadding,
|
|
1893
|
-
visibleInfo.endWithPadding,
|
|
1894
|
-
0,
|
|
1895
|
-
false,
|
|
1896
|
-
permanentItemList
|
|
1897
|
-
);
|
|
1898
|
-
let list = [];
|
|
1899
|
-
for (let range of pageUpdater.rangeList) {
|
|
1900
|
-
list = list.concat(innerData.slice(range.start, range.end + 1));
|
|
1901
|
-
}
|
|
1902
|
-
renderData.value = list;
|
|
1903
|
-
|
|
1904
|
-
onMounted(() => {
|
|
1905
|
-
mounted = true;
|
|
1906
|
-
_initRootTouch();
|
|
1907
|
-
for (let item of renderData.value) {
|
|
1908
|
-
_initItemViewTouch(toRaw(item.itemDivRef), item.index);
|
|
1909
|
-
}
|
|
1910
|
-
|
|
1911
|
-
if (visibleInfo.start) {
|
|
1912
|
-
_slideTo(visibleInfo.start, null);
|
|
1913
|
-
}
|
|
1914
|
-
|
|
1915
|
-
onItemFocus(templateParser.IdToIndex(focusId), preEdgeRect);
|
|
1916
|
-
|
|
1917
|
-
if (props.enableItemRenderBreak) {
|
|
1918
|
-
nextTick(() => {
|
|
1919
|
-
itemRender.value = true;
|
|
1920
|
-
});
|
|
1921
|
-
}
|
|
1922
|
-
});
|
|
1923
|
-
|
|
1924
|
-
onUpdated(() => {
|
|
1925
|
-
for (let item of renderData.value) {
|
|
1926
|
-
if (!item.touchInited) {
|
|
1927
|
-
_initItemViewTouch(toRaw(item.itemDivRef), item.index);
|
|
1928
|
-
}
|
|
1929
|
-
}
|
|
1930
|
-
});
|
|
1931
|
-
|
|
1932
|
-
onBeforeUnmount(() => {
|
|
1933
|
-
mounted = false;
|
|
1934
|
-
if (props.dispatcher) {
|
|
1935
|
-
props.dispatcher.unregisterComponent();
|
|
1936
|
-
}
|
|
1937
|
-
});
|
|
1938
387
|
|
|
1939
388
|
defineExpose(exportObject);
|
|
1940
389
|
</script>
|
|
@@ -1949,8 +398,14 @@ defineExpose(exportObject);
|
|
|
1949
398
|
overflow: disableClip ? null : 'hidden',
|
|
1950
399
|
}"
|
|
1951
400
|
>
|
|
1952
|
-
<div
|
|
401
|
+
<div
|
|
402
|
+
:style="{
|
|
403
|
+
left: widgetRectInfo.padding.left,
|
|
404
|
+
top: widgetRectInfo.padding.top,
|
|
405
|
+
}"
|
|
406
|
+
>
|
|
1953
407
|
<div
|
|
408
|
+
id="slideDiv"
|
|
1954
409
|
key="touchcontainer"
|
|
1955
410
|
ref="slideDiv"
|
|
1956
411
|
:style="{
|
|
@@ -1968,58 +423,62 @@ defineExpose(exportObject);
|
|
|
1968
423
|
ref="focusNode"
|
|
1969
424
|
:name="name"
|
|
1970
425
|
:onAction="{
|
|
1971
|
-
onFocus:
|
|
1972
|
-
onBlur:
|
|
1973
|
-
onKeyDown:
|
|
1974
|
-
onCustomerEvent:
|
|
426
|
+
onFocus: focusBlockOnFocus,
|
|
427
|
+
onBlur: focusBlockOnBlur,
|
|
428
|
+
onKeyDown: focusBlockOnKeyDown,
|
|
429
|
+
onCustomerEvent: focusBlockOnCustomerEvent,
|
|
1975
430
|
}"
|
|
1976
431
|
>
|
|
1977
432
|
<div
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
433
|
+
id="itemResizeSlide"
|
|
434
|
+
key="itemResizeSlide"
|
|
435
|
+
ref="itemResizeSlideDiv"
|
|
1981
436
|
:style="{
|
|
1982
|
-
left:
|
|
1983
|
-
top:
|
|
1984
|
-
width: item.data.width,
|
|
1985
|
-
height: item.data.height,
|
|
1986
|
-
zIndex: item.controller.zIndex,
|
|
437
|
+
left: itemResizeSlideLeft,
|
|
438
|
+
top: itemResizeSlideTop,
|
|
1987
439
|
}"
|
|
1988
440
|
>
|
|
1989
441
|
<div
|
|
1990
|
-
v-
|
|
1991
|
-
|
|
1992
|
-
"
|
|
1993
|
-
:
|
|
1994
|
-
|
|
442
|
+
v-for="item in renderData"
|
|
443
|
+
:key="pageUpdateToken + '_' + item.index"
|
|
444
|
+
:ref="item.divRef"
|
|
445
|
+
:style="{
|
|
446
|
+
...item.renderStyle,
|
|
447
|
+
}"
|
|
1995
448
|
>
|
|
1996
|
-
<
|
|
1997
|
-
|
|
449
|
+
<div
|
|
450
|
+
v-if="!enableItemRenderBreak || item.mounted || itemRender"
|
|
1998
451
|
:key="renderBreakKey"
|
|
1999
|
-
:
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
452
|
+
:ref="item.slotRef"
|
|
453
|
+
>
|
|
454
|
+
<slot
|
|
455
|
+
name="renderItem"
|
|
456
|
+
:key="renderBreakKey"
|
|
457
|
+
:data="item.customerData"
|
|
458
|
+
:onEdge="_onFocusableItemEdge"
|
|
459
|
+
:onAction="item.registerObj"
|
|
460
|
+
:query="item.query"
|
|
461
|
+
:onItemEdge="_onFocusableItemEdge"
|
|
462
|
+
></slot>
|
|
463
|
+
</div>
|
|
464
|
+
<div
|
|
465
|
+
v-if="
|
|
466
|
+
enableItemRenderBreak &&
|
|
467
|
+
placeHolderSetting &&
|
|
468
|
+
!item.mounted.value
|
|
469
|
+
"
|
|
470
|
+
:style="{
|
|
471
|
+
width:
|
|
472
|
+
item.renderStyle.width -
|
|
473
|
+
(placeHolderSetting.gap ? placeHolderSetting.gap : 0),
|
|
474
|
+
height:
|
|
475
|
+
item.renderStyle.height -
|
|
476
|
+
(placeHolderSetting.gap ? placeHolderSetting.gap : 0),
|
|
477
|
+
backgroundColor: placeHolderSetting.backgroundColor,
|
|
478
|
+
borderRadius: placeHolderSetting.borderRadius,
|
|
479
|
+
}"
|
|
480
|
+
></div>
|
|
2005
481
|
</div>
|
|
2006
|
-
<div
|
|
2007
|
-
v-if="
|
|
2008
|
-
enableItemRenderBreak &&
|
|
2009
|
-
placeHolderSetting &&
|
|
2010
|
-
!item.slotMounted.value
|
|
2011
|
-
"
|
|
2012
|
-
:style="{
|
|
2013
|
-
width:
|
|
2014
|
-
item.data.width -
|
|
2015
|
-
(placeHolderSetting.gap ? placeHolderSetting.gap : 0),
|
|
2016
|
-
height:
|
|
2017
|
-
item.data.height -
|
|
2018
|
-
(placeHolderSetting.gap ? placeHolderSetting.gap : 0),
|
|
2019
|
-
backgroundColor: placeHolderSetting.backgroundColor,
|
|
2020
|
-
borderRadius: placeHolderSetting.borderRadius,
|
|
2021
|
-
}"
|
|
2022
|
-
></div>
|
|
2023
482
|
</div>
|
|
2024
483
|
</jsv-focus-block>
|
|
2025
484
|
</div>
|