Skip to content
Snippets Groups Projects
Commit bcec1fc6 authored by rhenck's avatar rhenck
Browse files

[editor] Improve drag and drop of multiple elements

Can now be repositioned and moved between sections properly.
parent 057544dd
No related branches found
No related tags found
No related merge requests found
......@@ -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.
......
......@@ -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"
......
......@@ -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"
......
......@@ -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);
});
}
}
......
......@@ -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
});
......
......@@ -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>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment