From bcec1fc68384d88474edf9dcba9c43959d590656 Mon Sep 17 00:00:00 2001 From: rhenck <richard.henck@iqb.hu-berlin.de> Date: Sun, 26 Sep 2021 12:51:25 +0200 Subject: [PATCH] [editor] Improve drag and drop of multiple elements Can now be repositioned and moved between sections properly. --- .../canvas/canvas-element-overlay.ts | 4 +- .../dynamic-canvas-overlay.component.ts | 11 ++--- .../canvas/page-canvas.component.html | 2 +- .../page-view/canvas/page-canvas.component.ts | 44 ++++++++++--------- .../canvas/section-dynamic.component.ts | 5 +-- .../canvas/static-canvas-overlay.component.ts | 24 +++++----- 6 files changed, 45 insertions(+), 45 deletions(-) diff --git a/projects/editor/src/app/components/unit-view/page-view/canvas/canvas-element-overlay.ts b/projects/editor/src/app/components/unit-view/page-view/canvas/canvas-element-overlay.ts index d9266e73e..cdd435c11 100644 --- a/projects/editor/src/app/components/unit-view/page-view/canvas/canvas-element-overlay.ts +++ b/projects/editor/src/app/components/unit-view/page-view/canvas/canvas-element-overlay.ts @@ -19,7 +19,7 @@ export abstract class CanvasElementOverlay implements OnInit, OnDestroy { @Input() element!: UnitUIElement; @Input() viewMode: boolean = false; @ViewChild('elementContainer', { read: ViewContainerRef, static: true }) private elementContainer!: ViewContainerRef; - selected = false; + isSelected = false; protected childComponent!: ComponentRef<ElementComponent>; private ngUnsubscribe = new Subject<void>(); @@ -72,7 +72,7 @@ export abstract class CanvasElementOverlay implements OnInit, OnDestroy { } setSelected(newValue: boolean): void { - this.selected = newValue; + this.isSelected = newValue; // This avoids: "NG0100: Expression has changed after it was checked" // The selection service may change the "selected" variable after onInit has run. // Therefore we need to run it again after this. diff --git a/projects/editor/src/app/components/unit-view/page-view/canvas/dynamic-canvas-overlay.component.ts b/projects/editor/src/app/components/unit-view/page-view/canvas/dynamic-canvas-overlay.component.ts index ee21c0efe..7458064d2 100644 --- a/projects/editor/src/app/components/unit-view/page-view/canvas/dynamic-canvas-overlay.component.ts +++ b/projects/editor/src/app/components/unit-view/page-view/canvas/dynamic-canvas-overlay.component.ts @@ -8,12 +8,13 @@ import { UnitUIElement } from '../../../../../../../common/unit'; @Component({ selector: 'app-dynamic-canvas-overlay', template: ` - <div #draggableElement class="draggable-element" [class.draggable-element-selected]="selected" - cdkDrag [cdkDragData]="{dragType: 'move', element: element}" [cdkDragDisabled]="!selected" - (click)="selectElement($event.shiftKey)" (dblclick)="openEditDialog()" (cdkDragStarted)="selectElement()" + <div #draggableElement class="draggable-element" [class.draggable-element-selected]="isSelected" + cdkDrag [cdkDragData]="{dragType: 'move', element: element}" [cdkDragDisabled]="!isSelected" + (click)="selectElement($event.shiftKey)" (dblclick)="openEditDialog()" + (cdkDragStarted)="!isSelected && selectElement()" [style.height.%]="100" - [style.border]="selected ? '1px solid' : ''"> - <div *ngIf="selected" class="resizeHandle" + [style.border]="isSelected ? '1px solid' : ''"> + <div *ngIf="isSelected" class="resizeHandle" cdkDrag [cdkDragData]="{dragType: 'resize', element: element}" (cdkDragStarted)="dragStart()" (cdkDragEnded)="dragEnd()" (cdkDragMoved)="resizeElement($event)" cdkDragBoundary=".section-wrapper" diff --git a/projects/editor/src/app/components/unit-view/page-view/canvas/page-canvas.component.html b/projects/editor/src/app/components/unit-view/page-view/canvas/page-canvas.component.html index 3324f2d3c..93b7cfda9 100644 --- a/projects/editor/src/app/components/unit-view/page-view/canvas/page-canvas.component.html +++ b/projects/editor/src/app/components/unit-view/page-view/canvas/page-canvas.component.html @@ -31,7 +31,7 @@ [section]="section" [sectionIndex]="i" [isSelected]="selectionService.selectedPageSectionIndex === i" [dropListList]="dropListList" - (transferElement)="moveElementBetweenSections($event.element, + (transferElement)="moveElementsBetweenSections(selectionService.getSelectedElements(), $event.previousSectionIndex, $event.newSectionIndex)" (mouseover)="hoveredSection = i" (mouseleave)="hoveredSection = -1" diff --git a/projects/editor/src/app/components/unit-view/page-view/canvas/page-canvas.component.ts b/projects/editor/src/app/components/unit-view/page-view/canvas/page-canvas.component.ts index 034e0ff3d..0b05c56f2 100644 --- a/projects/editor/src/app/components/unit-view/page-view/canvas/page-canvas.component.ts +++ b/projects/editor/src/app/components/unit-view/page-view/canvas/page-canvas.component.ts @@ -65,37 +65,39 @@ export class PageCanvasComponent implements OnInit, OnDestroy { }); } - moveElementBetweenSections(element: UnitUIElement, previousSectionIndex: number, newSectionIndex: number): void { - this.unitService.transferElement([element], + moveElementsBetweenSections(elements: UnitUIElement[], previousSectionIndex: number, newSectionIndex: number): void { + this.unitService.transferElement(elements, this.page.sections[previousSectionIndex], this.page.sections[newSectionIndex]); } elementDropped(event: CdkDragDrop<DropListData>): void { - const sourceItemModel = (event.item.data as DragItemData).element; + const selectedElements = this.selectionService.getSelectedElements(); if (event.previousContainer !== event.container) { - this.moveElementBetweenSections(event.item.data.element, + this.moveElementsBetweenSections(selectedElements, event.previousContainer.data.sectionIndex, event.container.data.sectionIndex); } else { - let newXPosition = sourceItemModel.xPosition + event.distance.x; - if (newXPosition < 0) { - newXPosition = 0; - } - if (newXPosition > this.page.maxWidth - sourceItemModel.width) { - newXPosition = this.page.maxWidth - sourceItemModel.width; - } - this.unitService.updateElementProperty(this.selectionService.getSelectedElements(), 'xPosition', newXPosition); - - let newYPosition = sourceItemModel.yPosition + event.distance.y; - if (newYPosition < 0) { - newYPosition = 0; - } - if (newYPosition > this.getPageHeight() - sourceItemModel.height) { - newYPosition = this.getPageHeight() - sourceItemModel.height; - } - this.unitService.updateElementProperty(this.selectionService.getSelectedElements(), 'yPosition', newYPosition); + selectedElements.forEach((element: UnitUIElement) => { + let newXPosition = element.xPosition + event.distance.x; + if (newXPosition < 0) { + newXPosition = 0; + } + if (newXPosition > this.page.maxWidth - element.width) { + newXPosition = this.page.maxWidth - element.width; + } + this.unitService.updateElementProperty([element], 'xPosition', newXPosition); + + let newYPosition = element.yPosition + event.distance.y; + if (newYPosition < 0) { + newYPosition = 0; + } + if (newYPosition > this.getPageHeight() - element.height) { + newYPosition = this.getPageHeight() - element.height; + } + this.unitService.updateElementProperty([element], 'yPosition', newYPosition); + }); } } diff --git a/projects/editor/src/app/components/unit-view/page-view/canvas/section-dynamic.component.ts b/projects/editor/src/app/components/unit-view/page-view/canvas/section-dynamic.component.ts index e5da1f3b8..df1a210c0 100644 --- a/projects/editor/src/app/components/unit-view/page-view/canvas/section-dynamic.component.ts +++ b/projects/editor/src/app/components/unit-view/page-view/canvas/section-dynamic.component.ts @@ -68,9 +68,7 @@ export class SectionDynamicComponent { @Input() sectionIndex!: number; @Input() dropListList!: string[]; @Input() isSelected!: boolean; - @Output() transferElement = new EventEmitter<{ element: UnitUIElement, - previousSectionIndex: number, - newSectionIndex: number }>(); + @Output() transferElement = new EventEmitter<{ previousSectionIndex: number, newSectionIndex: number }>(); dragging = false; draggingElementWidth: number | undefined = 0; @@ -84,7 +82,6 @@ export class SectionDynamicComponent { // Move element to other section - handled by parent (page-canvas). if (event.previousContainer.data.sectionIndex !== event.container.data.sectionIndex) { this.transferElement.emit({ - element: event.item.data.element, previousSectionIndex: event.previousContainer.data.sectionIndex, newSectionIndex: event.container.data.sectionIndex }); diff --git a/projects/editor/src/app/components/unit-view/page-view/canvas/static-canvas-overlay.component.ts b/projects/editor/src/app/components/unit-view/page-view/canvas/static-canvas-overlay.component.ts index dae3bee20..00aadf61a 100644 --- a/projects/editor/src/app/components/unit-view/page-view/canvas/static-canvas-overlay.component.ts +++ b/projects/editor/src/app/components/unit-view/page-view/canvas/static-canvas-overlay.component.ts @@ -6,28 +6,28 @@ import { CanvasElementOverlay } from './canvas-element-overlay'; selector: 'app-static-canvas-overlay', template: ` <!-- Is also a droplist to catch the resize drop and not let it bubble up to the canvas drop handler. --> - <div class="draggable-element" [class.draggable-element-selected]="selected" + <div class="draggable-element" [class.draggable-element-selected]="isSelected" cdkDrag [cdkDragData]="{dragType: 'move', element: element}" - (click)="selectElement($event.shiftKey)" (cdkDragStarted)="selectElement()" + (click)="selectElement($event.shiftKey)" (cdkDragStarted)="!isSelected && selectElement()" (dblclick)="openEditDialog()" cdkDropList> <!-- Needs extra div because styling can interfere with drag and drop--> <div [style.position]="'absolute'" - [style.border]="selected ? '2px solid' : ''" + [style.border]="isSelected ? '2px solid' : ''" [style.width.px]="element.width" [style.height.px]="element.height" [style.left.px]="element.xPosition" [style.top.px]="element.yPosition" [style.z-index]="element.zIndex"> - <div *ngIf="selected" class="resizeHandle" - cdkDrag (cdkDragStarted)="resizeDragStart()" (cdkDragMoved)="resizeElement($event)" - cdkDragBoundary=".section-wrapper" - [style.right.px]="-1" - [style.bottom.px]="-7" - [style.z-index]="5"> - <mat-icon>aspect_ratio</mat-icon> - <div *cdkDragPlaceholder></div> - </div> + <div *ngIf="isSelected" class="resizeHandle" + cdkDrag (cdkDragStarted)="resizeDragStart()" (cdkDragMoved)="resizeElement($event)" + cdkDragBoundary=".section-wrapper" + [style.right.px]="-1" + [style.bottom.px]="-7" + [style.z-index]="5"> + <mat-icon>aspect_ratio</mat-icon> + <div *cdkDragPlaceholder></div> + </div> <ng-template #elementContainer></ng-template> </div> </div> -- GitLab