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

View File

@ -8,7 +8,6 @@
margin: 3px 0;
display: flex;
align-items: center;
cursor: pointer;
div {
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
.cdk-drag-preview {
box-shadow: none !important;
background-color: unset !important;
border-radius: 6px !important;
div {
div.backgroundColorLight {
box-sizing: border-box;
background-color: mat-color($background, background);
border-radius: 4px;

View File

@ -480,22 +480,38 @@ export class SortingTreeComponent<T extends Identifiable & Displayable> implemen
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.
*
* @param event The mouse event which emits the event.
*/
public mouseDown(event: MouseEvent): void {
this.pointer = {
position: {
x: event.x,
y: event.y
},
currentPosition: {
x: event.x,
y: event.y
}
};
this.initPointer(event.x, event.y);
}
public touchStart(event: TouchEvent): void {
const { clientX, clientY }: { clientX: number; clientY: number } = event.touches[0];
this.initPointer(Math.round(clientX), Math.round(clientY));
}
/**
@ -551,16 +567,22 @@ export class SortingTreeComponent<T extends Identifiable & Displayable> implemen
*/
private getDirection(): Movement {
const movement = new Movement();
movement.verticalMove =
this.nextNode.startPosition < this.nextNode.nextPosition
? Direction.DOWNWARDS
: this.nextNode.startPosition > this.nextNode.nextPosition
? Direction.UPWARDS
: Direction.NOWAY;
if (this.nextNode.startPosition < this.nextNode.nextPosition) {
movement.verticalMove = Direction.DOWNWARDS;
} else if (this.nextNode.startPosition > this.nextNode.nextPosition) {
movement.verticalMove = Direction.UPWARDS;
} else {
movement.verticalMove = Direction.NOWAY;
}
const deltaX = this.pointer.currentPosition.x - this.pointer.position.x;
movement.steps = Math.trunc(deltaX / 40);
movement.horizontalMove =
movement.steps > 0 ? Direction.RIGHT : movement.steps < 0 ? Direction.LEFT : Direction.NOWAY;
if (movement.steps > 0) {
movement.horizontalMove = Direction.RIGHT;
} else if (movement.steps < 0) {
movement.horizontalMove = Direction.LEFT;
} else {
movement.horizontalMove = Direction.NOWAY;
}
return movement;
}