Adds a handler for 'sorting-tree's

- Also fixes drag-handling for mobile-devices.
This commit is contained in:
GabrielMeyer 2019-08-26 12:00:23 +02:00
parent a05a81b1b2
commit 9a6efc0403
3 changed files with 97 additions and 67 deletions

View File

@ -1,47 +1,47 @@
<cdk-tree <cdk-tree
#osTree="cdkDropList" #osTree="cdkDropList"
[dataSource]="dataSource" [dataSource]="dataSource"
[treeControl]="treeControl" [treeControl]="treeControl"
cdkDropList cdkDropList
[cdkDropListData]="osTreeData" [cdkDropListData]="osTreeData"
(cdkDropListSorted)="sortItems($event)" (cdkDropListSorted)="sortItems($event)"
> >
<cdk-tree-node
<cdk-tree-node cdkDrag
cdkDrag [cdkDragData]="node"
[cdkDragData]="node" (cdkDragDropped)="onDrop(node)"
(cdkDragDropped)="onDrop(node)" (mousedown)="mouseDown($event)"
(mousedown)="mouseDown($event)" (mouseup)="mouseUp()"
(mouseup)="mouseUp($event)" (touchstart)="touchStart($event)"
(cdkDragStarted)="startsDrag($event)" (touchend)="mouseUp()"
(cdkDragMoved)="moveItem($event)" (cdkDragStarted)="startsDrag($event)"
*cdkTreeNodeDef="let node" (cdkDragMoved)="moveItem($event)"
[style.display]="shouldRender(node) ? 'flex' : 'none'" *cdkTreeNodeDef="let node"
[style.padding-left]="node.level * 40 + 'px'"> [style.display]="shouldRender(node) ? 'flex' : 'none'"
<div class="backgroundColorLight"> [style.padding-left]="node.level * 40 + 'px'"
<button >
*ngIf="!hasChild" <div class="backgroundColorLight">
mat-icon-button <span cdkDragHandle>
disabled></button> <mat-icon>drag_indicator</mat-icon>
<button </span>
*ngIf="hasChild" <button *ngIf="!hasChild" mat-icon-button disabled></button>
mat-icon-button <button
cdkTreeNodeToggle *ngIf="hasChild"
[attr.aria-label]="'toggle ' + node.filename" mat-icon-button
(click)="handleClick(node, true)" cdkTreeNodeToggle
[style.visibility]="node.expandable ? 'visible' : 'hidden'"> [attr.aria-label]="'toggle ' + node.filename"
<mat-icon (click)="handleClick(node, true)"
[style.transform]="node.isExpanded ? 'rotate(90deg)' : 'rotate(0deg)'" [style.visibility]="node.expandable ? 'visible' : 'hidden'"
class="mat-icon-rtl-mirror"> >
chevron_right <mat-icon
</mat-icon> [style.transform]="node.isExpanded ? 'rotate(90deg)' : 'rotate(0deg)'"
</button> class="mat-icon-rtl-mirror"
<ng-container >
[ngTemplateOutlet]="innerNode" chevron_right
[ngTemplateOutletContext]="{item: node.item}"></ng-container> </mat-icon>
</div> </button>
<div <ng-container [ngTemplateOutlet]="innerNode" [ngTemplateOutletContext]="{ item: node.item }"></ng-container>
[style.margin-left]="placeholderLevel * 40 + 'px'" </div>
*cdkDragPlaceholder></div> <div [style.margin-left]="placeholderLevel * 40 + 'px'" *cdkDragPlaceholder></div>
</cdk-tree-node> </cdk-tree-node>
</cdk-tree> </cdk-tree>

View File

@ -8,7 +8,6 @@
margin: 3px 0; margin: 3px 0;
display: flex; display: flex;
align-items: center; align-items: center;
cursor: pointer;
div { div {
display: inherit; display: inherit;
@ -21,13 +20,22 @@
} }
} }
// Overwrite the handler
.cdk-drag-handle {
display: flex;
cursor: move;
width: 50px;
align-items: center;
justify-content: center;
}
// Overwrite the preview // Overwrite the preview
.cdk-drag-preview { .cdk-drag-preview {
box-shadow: none !important; box-shadow: none !important;
background-color: unset !important; background-color: unset !important;
border-radius: 6px !important; border-radius: 6px !important;
div { div.backgroundColorLight {
box-sizing: border-box; box-sizing: border-box;
background-color: mat-color($background, background); background-color: mat-color($background, background);
border-radius: 4px; border-radius: 4px;

View File

@ -480,22 +480,38 @@ export class SortingTreeComponent<T extends Identifiable & Displayable> implemen
this.calcNextPosition(); this.calcNextPosition();
} }
/**
* Initializes the `this.pointer` with the x- and y-coordinates,
* where the user starts the dragging.
*
* @param x The value of the x-position on screen.
* @param y The value of the y-position on screen.
*/
private initPointer(x: number, y: number): void {
this.pointer = {
position: {
x,
y
},
currentPosition: {
x,
y
}
};
}
/** /**
* Function to set the cursor position immediately if the user starts dragging a node. * Function to set the cursor position immediately if the user starts dragging a node.
* *
* @param event The mouse event which emits the event. * @param event The mouse event which emits the event.
*/ */
public mouseDown(event: MouseEvent): void { public mouseDown(event: MouseEvent): void {
this.pointer = { this.initPointer(event.x, event.y);
position: { }
x: event.x,
y: event.y public touchStart(event: TouchEvent): void {
}, const { clientX, clientY }: { clientX: number; clientY: number } = event.touches[0];
currentPosition: { this.initPointer(Math.round(clientX), Math.round(clientY));
x: event.x,
y: event.y
}
};
} }
/** /**
@ -551,16 +567,22 @@ export class SortingTreeComponent<T extends Identifiable & Displayable> implemen
*/ */
private getDirection(): Movement { private getDirection(): Movement {
const movement = new Movement(); const movement = new Movement();
movement.verticalMove = if (this.nextNode.startPosition < this.nextNode.nextPosition) {
this.nextNode.startPosition < this.nextNode.nextPosition movement.verticalMove = Direction.DOWNWARDS;
? Direction.DOWNWARDS } else if (this.nextNode.startPosition > this.nextNode.nextPosition) {
: this.nextNode.startPosition > this.nextNode.nextPosition movement.verticalMove = Direction.UPWARDS;
? Direction.UPWARDS } else {
: Direction.NOWAY; movement.verticalMove = Direction.NOWAY;
}
const deltaX = this.pointer.currentPosition.x - this.pointer.position.x; const deltaX = this.pointer.currentPosition.x - this.pointer.position.x;
movement.steps = Math.trunc(deltaX / 40); movement.steps = Math.trunc(deltaX / 40);
movement.horizontalMove = if (movement.steps > 0) {
movement.steps > 0 ? Direction.RIGHT : movement.steps < 0 ? Direction.LEFT : Direction.NOWAY; movement.horizontalMove = Direction.RIGHT;
} else if (movement.steps < 0) {
movement.horizontalMove = Direction.LEFT;
} else {
movement.horizontalMove = Direction.NOWAY;
}
return movement; return movement;
} }