@@ -2523,52 +2523,51 @@ export default class StageStore implements IStageStore {
2523
2523
}
2524
2524
2525
2525
/**
2526
- * 将选中的组件转换为组合
2527
- *
2528
- * 处理组件的流程如下:
2529
- *
2530
- * 1. 将被选中的组件移动到被选中的层级最高的组件之前
2531
- * 2. 查找需要删除和更新的组合
2532
- * 3. 在层级最高的组件后插入新的组合
2533
- * 4. 删除或者更新需要删除和更新的组合
2526
+ * 计算移动组件位置时,受影响的组件
2534
2527
*
2535
2528
* @param elements
2529
+ * @param targetElementGroup
2530
+ * @param targetElementGroupAncestors
2531
+ * @returns
2536
2532
*/
2537
- async createElementGroup ( elements : IElement [ ] , undoActionCallback : ElementActionCallback , redoActionCallback : ElementActionCallback ) : Promise < IElementGroup > {
2538
- if ( elements . length < 1 ) return ;
2539
- // 组合id集合
2540
- const elementIds : string [ ] = elements . map ( element => element . id ) ;
2541
- // 对给定的组件所属的链表节点进行重新排序
2542
- const sortedElements = this . sortElements ( elements ) ;
2543
- // 找到给定组件的层级最高的组件,我们将要把组合组件插入到这个组件之后
2544
- const targetElement = sortedElements [ sortedElements . length - 1 ] ;
2545
- // 目标组件所属的组合
2546
- const targetElementGroup = targetElement . group ;
2547
- // 目标组件所属的组合的祖先组件
2548
- const targetElementGroupAncestors = targetElementGroup ?. ancestorGroups ;
2549
- // 目标组件在目标组件所属的组合中的索引
2550
- let targetIndexOfGroupSubs = - 1 ;
2551
- // 计算目标组件在目标组件所属的组合中的索引
2552
- targetIndexOfGroupSubs = targetElementGroup ?. model . subIds . indexOf ( targetElement . id ) ;
2533
+ private _calcEffectedElementsOfMoved (
2534
+ elements : IElement [ ] ,
2535
+ targetElementGroup : IElementGroup ,
2536
+ targetElementGroupAncestors : IElementGroup [ ] ,
2537
+ ) : {
2538
+ actionParams : ElementsActionParam [ ] ;
2539
+ removedGroups : IElementGroup [ ] ;
2540
+ updatedGroups : IElementGroup [ ] ;
2541
+ outerLayerIdSet : Set < string > ;
2542
+ elementIdSet : Set < string > ;
2543
+ updatedGroupIdSet : Set < string > ;
2544
+ removedGroupIdSet : Set < string > ;
2545
+ } {
2546
+ // 组件id集合
2547
+ const elementIdSet : Set < string > = new Set ( ) ;
2548
+ elements . forEach ( element => {
2549
+ elementIdSet . add ( element . id ) ;
2550
+ } ) ;
2553
2551
// 需要删除或者更新的组合
2554
2552
const groupIdSet : Set < string > = new Set ( ) ;
2555
2553
// 需要删除的组合id集合,用于后续删除组合
2556
2554
const removedGroupIdSet : Set < string > = new Set ( ) ;
2557
2555
// 需要更新的组合id集合,用于后续更新组合
2558
2556
const updatedGroupIdSet : Set < string > = new Set ( ) ;
2559
- // 当前给定组件中的非子组件id集合
2560
- const nonSubIdSet : Set < string > = new Set ( ) ;
2557
+ // 外层组件id集合
2558
+ const outerLayerIdSet : Set < string > = new Set ( ) ;
2561
2559
// 组合添加之前的回调函数的参数
2562
2560
const actionParams : ElementsActionParam [ ] = [ ] ;
2563
2561
// 找到需要删除或者更新的组合
2564
2562
elements . forEach ( element => {
2565
2563
if ( element . isGroupSubject ) {
2566
- if ( ! element . group . isSelected ) {
2567
- groupIdSet . add ( element . model . groupId ) ;
2568
- nonSubIdSet . add ( element . id ) ;
2564
+ const groupId = element . model . groupId ;
2565
+ if ( ! elementIdSet . has ( groupId ) ) {
2566
+ groupIdSet . add ( groupId ) ;
2567
+ outerLayerIdSet . add ( element . id ) ;
2569
2568
}
2570
2569
} else {
2571
- nonSubIdSet . add ( element . id ) ;
2570
+ outerLayerIdSet . add ( element . id ) ;
2572
2571
}
2573
2572
// 标记需要移动位置的组件
2574
2573
actionParams . push ( {
@@ -2578,21 +2577,12 @@ export default class StageStore implements IStageStore {
2578
2577
} ) ;
2579
2578
// 获取排序后的组合集合
2580
2579
const groups : IElement [ ] = this . getOrderedElementsByIds ( Array . from ( groupIdSet ) ) ;
2581
- // 顶层组合集合
2582
- const nonSubElements : IElement [ ] = this . getOrderedElementsByIds ( Array . from ( nonSubIdSet ) ) ;
2583
-
2584
- /**
2585
- * 判断是否需要删除组合
2586
- *
2587
- * @param group
2588
- * @returns
2589
- */
2580
+ // 判断是否需要删除组合
2590
2581
function groupShouldRemove ( group : IElementGroup ) : boolean {
2591
2582
const subIds = group . model . subIds ;
2592
2583
// 如果组合内的所有子组件都在给定的组件集合内,则需要删除组合
2593
- return subIds . every ( id => elementIds . includes ( id ) || subIds . every ( id => removedGroupIdSet . has ( id ) ) ) && group . id !== targetElementGroup ?. id && ! targetElementGroupAncestors ?. includes ( group ) ;
2584
+ return subIds . every ( id => elementIdSet . has ( id ) || subIds . every ( id => removedGroupIdSet . has ( id ) ) ) && group . id !== targetElementGroup ?. id && ! targetElementGroupAncestors ?. includes ( group ) ;
2594
2585
}
2595
-
2596
2586
// 找到需要删除或者更新的组合
2597
2587
groups . forEach ( group => {
2598
2588
// 如果组合内的所有子组件都在给定的组件集合内,则需要删除组合
@@ -2614,69 +2604,114 @@ export default class StageStore implements IStageStore {
2614
2604
} ) ;
2615
2605
2616
2606
// 获取需要删除的组合
2617
- const removedGroups = this . getOrderedElementsByIds ( Array . from ( removedGroupIdSet ) ) ;
2607
+ const removedGroups = this . getOrderedElementsByIds ( Array . from ( removedGroupIdSet ) ) as IElementGroup [ ] ;
2618
2608
removedGroups . forEach ( group => {
2619
2609
actionParams . push ( {
2620
2610
type : ElementActionTypes . Removed ,
2621
2611
data : [ group ] ,
2622
2612
} ) ;
2623
2613
} ) ;
2624
2614
// 获取需要更新的组合
2625
- const updatedGroups = this . getOrderedElementsByIds ( Array . from ( [ ...updatedGroupIdSet , ...( targetElementGroupAncestors ?. map ( group => group . id ) . flat ( ) || [ ] ) ] ) ) ;
2615
+ const updatedGroups = this . getOrderedElementsByIds ( Array . from ( [ ...updatedGroupIdSet , ...( targetElementGroupAncestors ?. map ( group => group . id ) . flat ( ) || [ ] ) ] ) ) as IElementGroup [ ] ;
2626
2616
updatedGroups . forEach ( group => {
2627
2617
actionParams . push ( {
2628
2618
type : ElementActionTypes . GroupUpdated ,
2629
2619
data : [ group ] ,
2630
2620
} ) ;
2631
2621
} ) ;
2622
+ return {
2623
+ actionParams,
2624
+ removedGroups,
2625
+ updatedGroups,
2626
+ outerLayerIdSet,
2627
+ elementIdSet,
2628
+ updatedGroupIdSet,
2629
+ removedGroupIdSet,
2630
+ } ;
2631
+ }
2632
+
2633
+ /**
2634
+ * 将选中的组件转换为组合
2635
+ *
2636
+ * 处理组件的流程如下:
2637
+ *
2638
+ * 1. 将被选中的组件移动到被选中的层级最高的组件之前
2639
+ * 2. 查找需要删除和更新的组合
2640
+ * 3. 在层级最高的组件后插入新的组合
2641
+ * 4. 删除或者更新需要删除和更新的组合
2642
+ *
2643
+ * @param elements
2644
+ */
2645
+ async createElementGroup ( elements : IElement [ ] , undoActionCallback : ElementActionCallback , redoActionCallback : ElementActionCallback ) : Promise < IElementGroup > {
2646
+ if ( elements . length < 1 ) return ;
2647
+ // 对给定的组件所属的链表节点进行重新排序
2648
+ const sortedElements = this . sortElements ( elements ) ;
2649
+ // 找到给定组件的层级最高的组件,我们将要把组合组件插入到这个组件之后
2650
+ const targetElement = sortedElements [ sortedElements . length - 1 ] ;
2651
+ // 目标组件所属的组合
2652
+ const targetElementGroup = targetElement . group ;
2653
+ // 目标组件所属的组合的祖先组件
2654
+ const targetElementGroupAncestors = targetElementGroup ?. ancestorGroups ;
2655
+ // 目标组件在目标组件所属的组合中的索引
2656
+ let targetIndexOfGroupSubs = - 1 ;
2657
+ // 计算目标组件在目标组件所属的组合中的索引
2658
+ targetIndexOfGroupSubs = targetElementGroup ?. model . subIds . indexOf ( targetElement . id ) ;
2659
+ // 计算移动组件位置时,受影响的组件
2660
+ const { actionParams, removedGroups, updatedGroups, outerLayerIdSet, elementIdSet, removedGroupIdSet } = this . _calcEffectedElementsOfMoved (
2661
+ sortedElements ,
2662
+ targetElementGroup ,
2663
+ targetElementGroupAncestors ,
2664
+ ) ;
2665
+ // 顶层组合集合
2666
+ const outerLayerElements : IElement [ ] = this . getOrderedElementsByIds ( Array . from ( outerLayerIdSet ) ) ;
2632
2667
await undoActionCallback ( actionParams ) ;
2633
2668
// 创建组合组件
2634
- const group = new ElementGroup ( this . _createElementGroupObject ( nonSubElements ) , this . shield ) ;
2669
+ const nGroup = new ElementGroup ( this . _createElementGroupObject ( outerLayerElements ) , this . shield ) ;
2635
2670
// 将前n-1个组件从链表中删除
2636
- const removeNodes = this . _removeNodesByElements ( elements . slice ( 0 , elements . length - 1 ) ) ;
2671
+ const removedNodes = this . _removeNodesByElements ( sortedElements . slice ( 0 , sortedElements . length - 1 ) ) ;
2637
2672
// 将removeNodes移动到targetElement之前
2638
- removeNodes . forEach ( node => {
2673
+ removedNodes . forEach ( node => {
2639
2674
// 插入到targetElement之前
2640
2675
this . _elementList . insertBefore ( node , targetElement . node , false ) ;
2641
2676
// 这里只更新非子组件的groupId
2642
- if ( nonSubIdSet . has ( node . value . id ) ) {
2677
+ if ( outerLayerIdSet . has ( node . value . id ) ) {
2643
2678
// 更新组件的groupId
2644
- this . updateElementModel ( node . value . id , { groupId : group . id } ) ;
2679
+ this . updateElementModel ( node . value . id , { groupId : nGroup . id } ) ;
2645
2680
}
2646
2681
} ) ;
2647
2682
// 如果目标组合存在,则需要维护目标组合与新建组合的父子关系
2648
2683
if ( targetElementGroup ) {
2649
2684
// 原始的目标组合的子组件id集合
2650
2685
const subIds = [ ...targetElementGroup . model . subIds ] ;
2651
2686
// 将目标组件id替换为新建组合的id
2652
- subIds . splice ( targetIndexOfGroupSubs , 1 , group . id ) ;
2687
+ subIds . splice ( targetIndexOfGroupSubs , 1 , nGroup . id ) ;
2653
2688
// 更新目标组合的子组件id集合
2654
2689
this . updateElementModel ( targetElementGroup . id , { subIds } ) ;
2655
2690
// 更新新建组合的groupId
2656
- group . model . groupId = targetElementGroup . id ;
2691
+ nGroup . model . groupId = targetElementGroup . id ;
2657
2692
}
2658
2693
// 将新建组合插入到targetElement之后
2659
- this . _insertNewGroup ( group , targetElement ) ;
2694
+ this . _insertNewGroup ( nGroup , targetElement ) ;
2660
2695
const groupAddedParams : ElementsActionParam = {
2661
2696
type : ElementActionTypes . Added ,
2662
- data : [ group ] ,
2697
+ data : [ nGroup ] ,
2663
2698
} ;
2664
2699
await undoActionCallback ( [ groupAddedParams ] ) ;
2665
2700
// 组合添加之前的回调函数的参数
2666
2701
actionParams . push ( groupAddedParams ) ;
2667
2702
// 移除需要删除的组合
2668
- removedGroups . forEach ( group => {
2669
- this . removeElement ( group ) ;
2703
+ removedGroups . forEach ( rGroup => {
2704
+ this . removeElement ( rGroup ) ;
2670
2705
} ) ;
2671
2706
// 更新需要更新的组合
2672
- updatedGroups . forEach ( group => {
2707
+ updatedGroups . forEach ( uGroup => {
2673
2708
// 计算组合的子组件id集合
2674
- const subIds = group . model . subIds . filter ( id => ! elementIds . includes ( id ) && ! removedGroupIdSet . has ( id ) ) ;
2709
+ const subIds = uGroup . model . subIds . filter ( id => ! elementIdSet . has ( id ) && ! removedGroupIdSet . has ( id ) ) ;
2675
2710
// 更新组合的子组件id集合
2676
- this . updateElementModel ( group . id , { subIds } ) ;
2711
+ this . updateElementModel ( uGroup . id , { subIds } ) ;
2677
2712
// 因为组合内的子组件发生变化,需要刷新组合的尺寸和位置
2678
- ( group as IElementGroup ) . refreshBySubs ( ) ;
2679
- group . refreshOriginals ( ) ;
2713
+ ( uGroup as IElementGroup ) . refreshBySubs ( ) ;
2714
+ uGroup . refreshOriginals ( ) ;
2680
2715
} ) ;
2681
2716
await redoActionCallback ( actionParams ) ;
2682
2717
}
@@ -3332,12 +3367,67 @@ export default class StageStore implements IStageStore {
3332
3367
3333
3368
/**
3334
3369
* 将组件移动到指定位置
3335
- *
3336
- * @param ids
3337
- * @param target
3338
- * @param dropType
3370
+ *
3371
+ * @param ids
3372
+ * @param target
3373
+ * @param dropType
3374
+ * @param undoActionCallback
3375
+ * @param redoActionCallback
3376
+ * @returns
3339
3377
*/
3340
- async moveElementsTo ( ids : string [ ] , target : string , dropType : TreeNodeDropType ) : Promise < void > {
3341
-
3378
+ async moveElementsTo ( ids : string [ ] , target : string , dropType : TreeNodeDropType , undoActionCallback : ElementActionCallback , redoActionCallback : ElementActionCallback ) : Promise < void > {
3379
+ if ( ids . length === 0 || ! target ) return ;
3380
+ const elements = this . getOrderedElementsByIds ( ids ) ;
3381
+ let targetElement = this . getElementById ( target ) ;
3382
+ // 获取所有要移动的组件的组合id集合
3383
+ const groupIds : Set < string > = new Set ( ) ;
3384
+ elements . forEach ( element => {
3385
+ if ( element . model . type === CreatorTypes . group ) {
3386
+ groupIds . add ( element . id ) ;
3387
+ }
3388
+ } ) ;
3389
+ // 目标组合的id
3390
+ let targetGroupId : string | undefined = undefined ;
3391
+ // 目标组合
3392
+ let targetGroup : IElementGroup | undefined = undefined ;
3393
+ // 目标组合的子组件id集合
3394
+ let targetSubIds : string [ ] = [ ] ;
3395
+ // 目标组件在目标组合中的索引
3396
+ let targetIndexOfGroupSubs = - 1 ;
3397
+ // 插入到组合内部的操作
3398
+ if ( dropType === TreeNodeDropType . inner && targetElement . isGroup ) {
3399
+ targetGroupId = targetElement . id ;
3400
+ targetSubIds = targetElement . model . subIds ;
3401
+ targetElement = this . _elementsMap . get ( targetSubIds [ targetSubIds . length - 1 ] ) ;
3402
+ } else if ( targetElement . isGroupSubject ) {
3403
+ targetGroupId = targetElement . model . groupId ;
3404
+ targetSubIds = this . _elementsMap . get ( targetGroupId ) ?. model . subIds || [ ] ;
3405
+ targetIndexOfGroupSubs = targetSubIds . indexOf ( targetElement . id ) ;
3406
+ targetGroup = targetElement . group ;
3407
+ }
3408
+ const actionParams : ElementsActionParam [ ] = [ ] ;
3409
+ const updatedGroupIdSet : Set < string > = new Set ( ) ;
3410
+ const removedGroupIdSet : Set < string > = new Set ( ) ;
3411
+ elements . forEach ( element => { } ) ;
3412
+ let newSubIds : string [ ] = [ ] ;
3413
+ if ( targetGroupId ) {
3414
+ actionParams . push ( {
3415
+ type : ElementActionTypes . GroupUpdated ,
3416
+ data : [ this . getElementById ( targetGroupId ) ] ,
3417
+ } ) ;
3418
+ targetGroup = this . getElementById ( targetGroupId ) as IElementGroup ;
3419
+ }
3420
+ await undoActionCallback ( actionParams ) ;
3421
+ if ( targetGroup ) {
3422
+ if ( targetIndexOfGroupSubs > - 1 ) {
3423
+ targetSubIds . splice ( targetIndexOfGroupSubs + 1 , 0 , ...newSubIds ) ;
3424
+ } else {
3425
+ targetSubIds . push ( ...newSubIds ) ;
3426
+ }
3427
+ this . updateElementModel ( targetGroupId , { subIds : targetSubIds } ) ;
3428
+ targetGroup . refreshBySubs ( ) ;
3429
+ targetGroup . refreshOriginals ( ) ;
3430
+ }
3431
+ await redoActionCallback ( actionParams ) ;
3342
3432
}
3343
3433
}
0 commit comments