Skip to content

Commit 23fd287

Browse files
author
shuzarevich
committed
feat(connection): implement waypoints management with drag-and-drop support
- Added FConnectionWaypoints component for managing waypoints - Created HTML template for rendering waypoints and candidates - Implemented methods for inserting, selecting, moving, and removing waypoints - Introduced findExistingWaypoint utility for waypoint detection - Updated moveConnectionWaypointHandler to support waypoint manipulation
1 parent a879e78 commit 23fd287

File tree

14 files changed

+198
-155
lines changed

14 files changed

+198
-155
lines changed

projects/f-flow/src/f-connection-v2/components/connection-control-points/f-connection-control-points.html

Lines changed: 0 additions & 21 deletions
This file was deleted.

projects/f-flow/src/f-connection-v2/components/connection-control-points/f-connection-control-points.ts

Lines changed: 0 additions & 19 deletions
This file was deleted.

projects/f-flow/src/f-connection-v2/components/connection-control-points/models/f-connection-control-points-base.ts

Lines changed: 0 additions & 42 deletions
This file was deleted.

projects/f-flow/src/f-connection-v2/components/connection-control-points/models/index.ts

Lines changed: 0 additions & 2 deletions
This file was deleted.

projects/f-flow/src/f-connection-v2/components/connection-control-points/utils/find-pivot.ts

Lines changed: 0 additions & 14 deletions
This file was deleted.

projects/f-flow/src/f-connection-v2/components/connection-control-points/utils/index.ts

Lines changed: 0 additions & 4 deletions
This file was deleted.
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
@if (visibility()) {
2+
<svg xmlns="http://www.w3.org/2000/svg">
3+
<g>
4+
@for (candidate of candidates(); track $index) {
5+
<circle
6+
[attr.r]="radius()"
7+
class="f-candidate"
8+
[attr.cx]="candidate.point.x"
9+
[attr.cy]="candidate.point.y"
10+
></circle>
11+
}
12+
@for (point of waypoints(); track $index) {
13+
<circle
14+
[attr.r]="radius()"
15+
(contextmenu)="$event.preventDefault();"
16+
class="f-waypoint"
17+
[attr.cx]="point.x"
18+
[attr.cy]="point.y"
19+
></circle>
20+
}
21+
</g>
22+
</svg>
23+
}
24+
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import {
2+
booleanAttribute,
3+
ChangeDetectionStrategy,
4+
Component,
5+
input,
6+
model,
7+
numberAttribute,
8+
} from '@angular/core';
9+
import { F_CONNECTION_WAYPOINTS, FConnectionWaypointsBase } from './models';
10+
import { IPoint } from '@foblex/2d';
11+
12+
@Component({
13+
selector: 'f-connection-waypoints',
14+
templateUrl: './f-connection-waypoints.html',
15+
styleUrls: ['./f-connection-waypoints.scss'],
16+
standalone: true,
17+
changeDetection: ChangeDetectionStrategy.OnPush,
18+
host: {
19+
class: 'f-component f-connection-waypoints',
20+
},
21+
providers: [{ provide: F_CONNECTION_WAYPOINTS, useExisting: FConnectionWaypoints }],
22+
})
23+
export class FConnectionWaypoints extends FConnectionWaypointsBase {
24+
public override readonly radius = input(4, {
25+
transform: numberAttribute,
26+
});
27+
public override readonly waypoints = model<IPoint[]>([]);
28+
29+
public override readonly visibility = input(true, {
30+
transform: booleanAttribute,
31+
});
32+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import { ElementRef, inject, InjectionToken, ModelSignal, signal, Signal } from '@angular/core';
2+
import { IWaypointCandidate } from './i-waypoint-candidate';
3+
import { IPoint, PointExtensions } from '@foblex/2d';
4+
5+
export const F_CONNECTION_WAYPOINTS = new InjectionToken<FConnectionWaypointsBase>(
6+
'F_CONNECTION_WAYPOINTS',
7+
);
8+
9+
export abstract class FConnectionWaypointsBase {
10+
public readonly hostElement = inject(ElementRef<SVGElement>).nativeElement;
11+
12+
public readonly candidates = signal<IWaypointCandidate[]>([]);
13+
14+
public abstract waypoints: ModelSignal<IPoint[]>;
15+
public abstract radius: Signal<number>;
16+
public abstract visibility: Signal<boolean>;
17+
18+
protected _activeIndex = signal(-1)
19+
private _pivots: IPoint[] = [];
20+
21+
public insert(candidate: IWaypointCandidate): void {
22+
const current = this.waypoints().slice();
23+
24+
this._activeIndex.set(Math.max(0, Math.min(candidate.chainIndex, current.length)));
25+
26+
current.splice(this._activeIndex(), 0, { ...candidate.point });
27+
this.waypoints.set(current);
28+
this._pivots = current;
29+
}
30+
31+
public select(pivot: IPoint): void {
32+
this._activeIndex.set(this.waypoints().findIndex((x) => PointExtensions.isEqual(pivot, x)));
33+
this._pivots = this.waypoints();
34+
}
35+
36+
public remove(pivot: IPoint): void {
37+
const index = this.waypoints().findIndex((x) => PointExtensions.isEqual(pivot, x));
38+
if (index === -1) {
39+
throw new Error('Waypoint to delete not found');
40+
}
41+
const current = this.waypoints().slice();
42+
current.splice(index, 1);
43+
this.waypoints.set(current);
44+
this._activeIndex.set(-1);
45+
}
46+
47+
public move(point: IPoint): void {
48+
this._pivots[this._activeIndex()] = { ...point };
49+
}
50+
51+
public update(): void {
52+
this.waypoints.set([...this._pivots]);
53+
// this._activeIndex.set(-1);
54+
}
55+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export * from './f-connection-waypoints-base';
2+
export * from './i-waypoint-candidate';

0 commit comments

Comments
 (0)