diff --git a/projects/f-examples/extensions/grid-system-example/grid-system-example.component.html b/projects/f-examples/extensions/grid-system-example/grid-system-example.component.html
new file mode 100644
index 0000000..f56e139
--- /dev/null
+++ b/projects/f-examples/extensions/grid-system-example/grid-system-example.component.html
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+ I'm a node
+ I'm a node
+
+
diff --git a/projects/f-examples/extensions/grid-system-example/grid-system-example.component.scss b/projects/f-examples/extensions/grid-system-example/grid-system-example.component.scss
new file mode 100644
index 0000000..e31db81
--- /dev/null
+++ b/projects/f-examples/extensions/grid-system-example/grid-system-example.component.scss
@@ -0,0 +1,10 @@
+@use "../../flow-common";
+
+::ng-deep grid-system-example {
+ @include flow-common.connection;
+}
+
+.f-node {
+ @include flow-common.node;
+}
+
diff --git a/projects/f-examples/extensions/grid-system-example/grid-system-example.component.ts b/projects/f-examples/extensions/grid-system-example/grid-system-example.component.ts
new file mode 100644
index 0000000..7f55022
--- /dev/null
+++ b/projects/f-examples/extensions/grid-system-example/grid-system-example.component.ts
@@ -0,0 +1,22 @@
+import { ChangeDetectionStrategy, Component, ViewChild } from '@angular/core';
+import { FCanvasComponent, FFlowModule } from '@foblex/flow';
+
+@Component({
+ selector: 'grid-system-example',
+ styleUrls: [ './grid-system-example.component.scss' ],
+ templateUrl: './grid-system-example.component.html',
+ changeDetection: ChangeDetectionStrategy.OnPush,
+ standalone: true,
+ imports: [
+ FFlowModule,
+ ]
+})
+export class GridSystemExampleComponent {
+
+ @ViewChild(FCanvasComponent, { static: true })
+ public fCanvas!: FCanvasComponent;
+
+ public onLoaded(): void {
+ this.fCanvas.resetScaleAndCenter(false);
+ }
+}
diff --git a/projects/f-flow/package.json b/projects/f-flow/package.json
index db354ec..a581f79 100644
--- a/projects/f-flow/package.json
+++ b/projects/f-flow/package.json
@@ -1,6 +1,6 @@
{
"name": "@foblex/flow",
- "version": "17.0.5",
+ "version": "17.0.6",
"description": "An Angular library designed to simplify the creation and manipulation of dynamic flow. Provides components for flows, nodes, and connections, automating node manipulation and inter-node connections.",
"main": "index.js",
"types": "index.d.ts",
diff --git a/projects/f-flow/src/f-draggable/domain/get-node-padding/get-node-padding.execution.ts b/projects/f-flow/src/domain/f-node/get-node-padding/get-node-padding.execution.ts
similarity index 100%
rename from projects/f-flow/src/f-draggable/domain/get-node-padding/get-node-padding.execution.ts
rename to projects/f-flow/src/domain/f-node/get-node-padding/get-node-padding.execution.ts
diff --git a/projects/f-flow/src/f-draggable/domain/get-node-padding/get-node-padding.request.ts b/projects/f-flow/src/domain/f-node/get-node-padding/get-node-padding.request.ts
similarity index 100%
rename from projects/f-flow/src/f-draggable/domain/get-node-padding/get-node-padding.request.ts
rename to projects/f-flow/src/domain/f-node/get-node-padding/get-node-padding.request.ts
diff --git a/projects/f-flow/src/f-draggable/domain/get-node-padding/index.ts b/projects/f-flow/src/domain/f-node/get-node-padding/index.ts
similarity index 100%
rename from projects/f-flow/src/f-draggable/domain/get-node-padding/index.ts
rename to projects/f-flow/src/domain/f-node/get-node-padding/index.ts
diff --git a/projects/f-flow/src/f-draggable/domain/get-parent-nodes/get-parent-nodes.execution.ts b/projects/f-flow/src/domain/f-node/get-parent-nodes/get-parent-nodes.execution.ts
similarity index 62%
rename from projects/f-flow/src/f-draggable/domain/get-parent-nodes/get-parent-nodes.execution.ts
rename to projects/f-flow/src/domain/f-node/get-parent-nodes/get-parent-nodes.execution.ts
index 54f8c82..3b6a93c 100644
--- a/projects/f-flow/src/f-draggable/domain/get-parent-nodes/get-parent-nodes.execution.ts
+++ b/projects/f-flow/src/domain/f-node/get-parent-nodes/get-parent-nodes.execution.ts
@@ -1,4 +1,4 @@
-import { Injectable } from '@angular/core';
+import { inject, Injectable } from '@angular/core';
import { GetParentNodesRequest } from './get-parent-nodes.request';
import { FExecutionRegister, IExecution } from '@foblex/mediator';
import { FNodeBase } from '../../../f-node';
@@ -9,27 +9,24 @@ import { FComponentsStore } from '../../../f-storage';
export class GetParentNodesExecution
implements IExecution {
- constructor(
- private fComponentsStore: FComponentsStore
- ) {
- }
+ private _fComponentsStore = inject(FComponentsStore);
public handle(request: GetParentNodesRequest): FNodeBase[] {
- return this.getParentNodes(request.fNode, new Set(), []);
+ return this._getParentNodes(request.fNode, new Set(), []);
}
- private getParentNodes(fNode: FNodeBase, visited: Set, result: FNodeBase[]): FNodeBase[] {
+ private _getParentNodes(fNode: FNodeBase, visited: Set, result: FNodeBase[]): FNodeBase[] {
if (visited.has(fNode.fId)) {
throw new Error('Circular reference detected in the node hierarchy. Node id: ' + fNode.fId);
}
visited.add(fNode.fId);
- const parent = this.fComponentsStore.fNodes.find((x) => x.fId === fNode.fParentId);
+ const parent = this._fComponentsStore.fNodes.find((x) => x.fId === fNode.fParentId);
if (!parent) {
return result;
}
result.push(parent);
- return this.getParentNodes(parent, visited, result);
+ return this._getParentNodes(parent, visited, result);
}
}
diff --git a/projects/f-flow/src/f-draggable/domain/get-parent-nodes/get-parent-nodes.request.ts b/projects/f-flow/src/domain/f-node/get-parent-nodes/get-parent-nodes.request.ts
similarity index 100%
rename from projects/f-flow/src/f-draggable/domain/get-parent-nodes/get-parent-nodes.request.ts
rename to projects/f-flow/src/domain/f-node/get-parent-nodes/get-parent-nodes.request.ts
diff --git a/projects/f-flow/src/f-draggable/domain/get-parent-nodes/index.ts b/projects/f-flow/src/domain/f-node/get-parent-nodes/index.ts
similarity index 100%
rename from projects/f-flow/src/f-draggable/domain/get-parent-nodes/index.ts
rename to projects/f-flow/src/domain/f-node/get-parent-nodes/index.ts
diff --git a/projects/f-flow/src/domain/f-node/index.ts b/projects/f-flow/src/domain/f-node/index.ts
index e8ff167..3acd809 100644
--- a/projects/f-flow/src/domain/f-node/index.ts
+++ b/projects/f-flow/src/domain/f-node/index.ts
@@ -4,8 +4,12 @@ export * from './calculate-nodes-bounding-box';
export * from './calculate-nodes-bounding-box-normalized-position';
+export * from './get-node-padding';
+
export * from './get-nodes';
+export * from './get-parent-nodes';
+
export * from './update-node-when-state-or-size-changed';
export * from './remove-node-from-store';
diff --git a/projects/f-flow/src/domain/f-node/providers.ts b/projects/f-flow/src/domain/f-node/providers.ts
index 590f495..8efc03c 100644
--- a/projects/f-flow/src/domain/f-node/providers.ts
+++ b/projects/f-flow/src/domain/f-node/providers.ts
@@ -6,6 +6,8 @@ import { CalculateNodesBoundingBoxExecution } from './calculate-nodes-bounding-b
import {
CalculateNodesBoundingBoxNormalizedPositionExecution
} from './calculate-nodes-bounding-box-normalized-position';
+import { GetNodePaddingExecution } from './get-node-padding';
+import { GetParentNodesExecution } from './get-parent-nodes';
export const F_NODE_FEATURES = [
@@ -15,8 +17,12 @@ export const F_NODE_FEATURES = [
CalculateNodesBoundingBoxNormalizedPositionExecution,
+ GetNodePaddingExecution,
+
GetNodesExecution,
+ GetParentNodesExecution,
+
UpdateNodeWhenStateOrSizeChangedExecution,
RemoveNodeFromStoreExecution
diff --git a/projects/f-flow/src/f-draggable/domain/get-normalized-node-rect/get-normalized-node-rect.execution.ts b/projects/f-flow/src/f-draggable/domain/get-normalized-node-rect/get-normalized-node-rect.execution.ts
deleted file mode 100644
index 0d55dd7..0000000
--- a/projects/f-flow/src/f-draggable/domain/get-normalized-node-rect/get-normalized-node-rect.execution.ts
+++ /dev/null
@@ -1,26 +0,0 @@
-import { Injectable } from '@angular/core';
-import { GetNormalizedNodeRectRequest } from './get-normalized-node-rect.request';
-import { IPoint, IRect, RectExtensions } from '@foblex/2d';
-import { FExecutionRegister, IExecution } from '@foblex/mediator';
-import { FComponentsStore } from '../../../f-storage';
-
-@Injectable()
-@FExecutionRegister(GetNormalizedNodeRectRequest)
-export class GetNormalizedNodeRectExecution
- implements IExecution {
-
- constructor(
- private fComponentsStore: FComponentsStore
- ) {
- }
-
- public handle(request: GetNormalizedNodeRectRequest): IRect {
- return this.normalizeRect(RectExtensions.fromElement(request.fNode.hostElement), request.fNode.position);
- }
-
- private normalizeRect(scaledRect: IRect, position: IPoint): IRect {
- const rect = RectExtensions.div(scaledRect, this.fComponentsStore.fCanvas!.transform.scale);
-
- return RectExtensions.initialize(position.x, position.y, rect.width, rect.height);
- }
-}
diff --git a/projects/f-flow/src/f-draggable/domain/get-normalized-node-rect/get-normalized-node-rect.request.ts b/projects/f-flow/src/f-draggable/domain/get-normalized-node-rect/get-normalized-node-rect.request.ts
deleted file mode 100644
index e85dd3b..0000000
--- a/projects/f-flow/src/f-draggable/domain/get-normalized-node-rect/get-normalized-node-rect.request.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import { FNodeBase } from '../../../f-node';
-
-export class GetNormalizedNodeRectRequest {
-
- constructor(
- public fNode: FNodeBase
- ) {
- }
-}
diff --git a/projects/f-flow/src/f-draggable/domain/get-normalized-node-rect/index.ts b/projects/f-flow/src/f-draggable/domain/get-normalized-node-rect/index.ts
deleted file mode 100644
index c444ed8..0000000
--- a/projects/f-flow/src/f-draggable/domain/get-normalized-node-rect/index.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-export * from './get-normalized-node-rect.execution';
-
-export * from './get-normalized-node-rect.request';
diff --git a/projects/f-flow/src/f-draggable/domain/get-normalized-parent-node-rect/get-normalized-parent-node-rect.execution.ts b/projects/f-flow/src/f-draggable/domain/get-normalized-parent-node-rect/get-normalized-parent-node-rect.execution.ts
index e86ce5e..54cba89 100644
--- a/projects/f-flow/src/f-draggable/domain/get-normalized-parent-node-rect/get-normalized-parent-node-rect.execution.ts
+++ b/projects/f-flow/src/f-draggable/domain/get-normalized-parent-node-rect/get-normalized-parent-node-rect.execution.ts
@@ -1,11 +1,11 @@
import { Injectable } from '@angular/core';
import { GetNormalizedParentNodeRectRequest } from './get-normalized-parent-node-rect.request';
import { IRect, RectExtensions } from '@foblex/2d';
-import { GetNormalizedNodeRectRequest } from '../get-normalized-node-rect';
import { FExecutionRegister, FMediator, IExecution } from '@foblex/mediator';
import { FNodeBase } from '../../../f-node';
import { FComponentsStore } from '../../../f-storage';
-import { GetNodePaddingRequest } from '../get-node-padding';
+import { GetNodePaddingRequest } from '../../../domain';
+import { GetNormalizedElementRectRequest } from '../../../domain';
@Injectable()
@FExecutionRegister(GetNormalizedParentNodeRectRequest)
@@ -32,18 +32,18 @@ export class GetNormalizedParentNodeRectExecution
}
private getParentRect(node: FNodeBase): IRect {
- const rect = this.getNormalizedNodeRect(node);
+ const rect = this._getNodeRect(node);
const padding = this.getNodePadding(node, rect);
return RectExtensions.initialize(
- rect.x + padding[0],
- rect.y + padding[1],
- rect.width - padding[0] - padding[2],
- rect.height - padding[1] - padding[3]
+ rect.x + padding[ 0 ],
+ rect.y + padding[ 1 ],
+ rect.width - padding[ 0 ] - padding[ 2 ],
+ rect.height - padding[ 1 ] - padding[ 3 ]
);
}
- private getNormalizedNodeRect(node: FNodeBase): IRect {
- return this.fMediator.send(new GetNormalizedNodeRectRequest(node));
+ private _getNodeRect(fNode: FNodeBase): IRect {
+ return this.fMediator.send(new GetNormalizedElementRectRequest(fNode.hostElement));
}
private getNodePadding(node: FNodeBase, rect: IRect): [ number, number, number, number ] {
diff --git a/projects/f-flow/src/f-draggable/domain/index.ts b/projects/f-flow/src/f-draggable/domain/index.ts
index a5d4d32..5c2178c 100644
--- a/projects/f-flow/src/f-draggable/domain/index.ts
+++ b/projects/f-flow/src/f-draggable/domain/index.ts
@@ -1,11 +1,5 @@
-export * from './get-node-padding';
-
-export * from './get-normalized-node-rect';
-
export * from './get-normalized-parent-node-rect';
-export * from './get-parent-nodes';
-
export * from './is-array-has-parent-node';
export * from './is-connection-under-node';
diff --git a/projects/f-flow/src/f-draggable/domain/is-array-has-parent-node/is-array-has-parent-node.execution.ts b/projects/f-flow/src/f-draggable/domain/is-array-has-parent-node/is-array-has-parent-node.execution.ts
index 250e2b8..b36e8f4 100644
--- a/projects/f-flow/src/f-draggable/domain/is-array-has-parent-node/is-array-has-parent-node.execution.ts
+++ b/projects/f-flow/src/f-draggable/domain/is-array-has-parent-node/is-array-has-parent-node.execution.ts
@@ -2,7 +2,7 @@ import { Injectable } from '@angular/core';
import { IsArrayHasParentNodeRequest } from './is-array-has-parent-node.request';
import { FExecutionRegister, FMediator, IExecution } from '@foblex/mediator';
import { FNodeBase } from '../../../f-node';
-import { GetParentNodesRequest } from '../get-parent-nodes';
+import { GetParentNodesRequest } from '../../../domain/f-node/get-parent-nodes';
@Injectable()
@FExecutionRegister(IsArrayHasParentNodeRequest)
diff --git a/projects/f-flow/src/f-draggable/domain/is-connection-under-node/is-connection-under-node.request.ts b/projects/f-flow/src/f-draggable/domain/is-connection-under-node/is-connection-under-node.request.ts
index e1919f7..87088c5 100644
--- a/projects/f-flow/src/f-draggable/domain/is-connection-under-node/is-connection-under-node.request.ts
+++ b/projects/f-flow/src/f-draggable/domain/is-connection-under-node/is-connection-under-node.request.ts
@@ -1,3 +1,2 @@
export class IsConnectionUnderNodeRequest {
-
}
diff --git a/projects/f-flow/src/f-draggable/domain/providers.ts b/projects/f-flow/src/f-draggable/domain/providers.ts
index 5c4b244..e052299 100644
--- a/projects/f-flow/src/f-draggable/domain/providers.ts
+++ b/projects/f-flow/src/f-draggable/domain/providers.ts
@@ -1,20 +1,11 @@
-import { GetNormalizedNodeRectExecution } from './get-normalized-node-rect';
-import { GetParentNodesExecution } from './get-parent-nodes';
import { IsArrayHasParentNodeExecution } from './is-array-has-parent-node';
import { GetNormalizedParentNodeRectExecution } from './get-normalized-parent-node-rect';
-import { GetNodePaddingExecution } from './get-node-padding';
import { IsConnectionUnderNodeExecution, IsConnectionUnderNodeValidator } from './is-connection-under-node';
export const DRAG_AND_DROP_COMMON_PROVIDERS = [
- GetNodePaddingExecution,
-
- GetNormalizedNodeRectExecution,
-
GetNormalizedParentNodeRectExecution,
- GetParentNodesExecution,
-
IsArrayHasParentNodeExecution,
IsConnectionUnderNodeExecution,
diff --git a/projects/f-flow/src/f-draggable/f-draggable-base.ts b/projects/f-flow/src/f-draggable/f-draggable-base.ts
index 123f4cd..0b4a168 100644
--- a/projects/f-flow/src/f-draggable/f-draggable-base.ts
+++ b/projects/f-flow/src/f-draggable/f-draggable-base.ts
@@ -21,6 +21,10 @@ export abstract class FDraggableBase extends DragAndDropBase {
public abstract fDropToGroup: EventEmitter;
+ public abstract vCellSize: number;
+
+ public abstract hCellSize: number;
+
protected constructor(
ngZone: ICanRunOutsideAngular | undefined
) {
diff --git a/projects/f-flow/src/f-draggable/f-draggable.directive.ts b/projects/f-flow/src/f-draggable/f-draggable.directive.ts
index 4a03e49..e7ceb9e 100644
--- a/projects/f-flow/src/f-draggable/f-draggable.directive.ts
+++ b/projects/f-flow/src/f-draggable/f-draggable.directive.ts
@@ -66,22 +66,29 @@ export class FDraggableDirective extends FDraggableBase implements OnInit, After
}
@Output()
- public override fSelectionChange: EventEmitter = new EventEmitter();
+ public override fSelectionChange = new EventEmitter();
@Output()
- public override fNodeIntersectedWithConnections: EventEmitter = new EventEmitter();
+ public override fNodeIntersectedWithConnections = new EventEmitter();
@Output()
- public override fCreateNode: EventEmitter = new EventEmitter();
+ public override fCreateNode = new EventEmitter();
@Output()
- public override fReassignConnection: EventEmitter = new EventEmitter();
+ public override fReassignConnection = new EventEmitter();
@Output()
- public override fCreateConnection: EventEmitter = new EventEmitter();
+ public override fCreateConnection = new EventEmitter();
@Output()
- public override fDropToGroup: EventEmitter = new EventEmitter();
+ public override fDropToGroup = new EventEmitter();
+
+ @Input()
+ public override vCellSize = 1;
+
+
+ @Input()
+ public override hCellSize = 1;
@ContentChildren(F_DRAG_AND_DROP_PLUGIN, { descendants: true })
private plugins!: QueryList;
diff --git a/projects/f-flow/src/f-draggable/node-resize/get-node-resize-restrictions/get-node-resize-restrictions.execution.ts b/projects/f-flow/src/f-draggable/node-resize/get-node-resize-restrictions/get-node-resize-restrictions.execution.ts
index 09f01cb..61acd2f 100644
--- a/projects/f-flow/src/f-draggable/node-resize/get-node-resize-restrictions/get-node-resize-restrictions.execution.ts
+++ b/projects/f-flow/src/f-draggable/node-resize/get-node-resize-restrictions/get-node-resize-restrictions.execution.ts
@@ -3,9 +3,10 @@ import { GetNodeResizeRestrictionsRequest } from './get-node-resize-restrictions
import { IRect, SizeExtensions } from '@foblex/2d';
import { INodeResizeRestrictions } from './i-node-resize-restrictions';
import { FExecutionRegister, FMediator, IExecution } from '@foblex/mediator';
-import { GetNodePaddingRequest, GetNormalizedParentNodeRectRequest } from '../../domain';
+import { GetNormalizedParentNodeRectRequest } from '../../domain';
import { GetNormalizedChildrenNodesRectRequest } from '../get-normalized-children-nodes-rect';
import { FNodeBase } from '../../../f-node';
+import { GetNodePaddingRequest } from '../../../domain';
@Injectable()
diff --git a/projects/f-flow/src/f-draggable/node-resize/get-normalized-children-nodes-rect/get-normalized-children-nodes-rect.execution.ts b/projects/f-flow/src/f-draggable/node-resize/get-normalized-children-nodes-rect/get-normalized-children-nodes-rect.execution.ts
index 15af09b..87d6058 100644
--- a/projects/f-flow/src/f-draggable/node-resize/get-normalized-children-nodes-rect/get-normalized-children-nodes-rect.execution.ts
+++ b/projects/f-flow/src/f-draggable/node-resize/get-normalized-children-nodes-rect/get-normalized-children-nodes-rect.execution.ts
@@ -3,8 +3,7 @@ import { GetNormalizedChildrenNodesRectRequest } from './get-normalized-children
import { IRect, RectExtensions } from '@foblex/2d';
import { FExecutionRegister, FMediator, IExecution } from '@foblex/mediator';
import { FNodeBase } from '../../../f-node';
-import { GetNormalizedNodeRectRequest } from '../../domain';
-import { GetDeepChildrenNodesAndGroupsRequest } from '../../../domain';
+import { GetDeepChildrenNodesAndGroupsRequest, GetNormalizedElementRectRequest } from '../../../domain';
@Injectable()
@FExecutionRegister(GetNormalizedChildrenNodesRectRequest)
@@ -28,8 +27,8 @@ export class GetNormalizedChildrenNodesRectExecution
return this.fMediator.send(new GetDeepChildrenNodesAndGroupsRequest(fId));
}
- private normalizeRect(node: FNodeBase): IRect {
- return this.fMediator.send(new GetNormalizedNodeRectRequest(node));
+ private normalizeRect(fNode: FNodeBase): IRect {
+ return this.fMediator.send(new GetNormalizedElementRectRequest(fNode.hostElement));
}
private concatRectWithParentPadding(rect: IRect, padding: [ number, number, number, number ]): IRect {
diff --git a/projects/f-flow/src/f-draggable/node-resize/node-resize.drag-handler.ts b/projects/f-flow/src/f-draggable/node-resize/node-resize.drag-handler.ts
index d02ce24..e1c6464 100644
--- a/projects/f-flow/src/f-draggable/node-resize/node-resize.drag-handler.ts
+++ b/projects/f-flow/src/f-draggable/node-resize/node-resize.drag-handler.ts
@@ -2,12 +2,12 @@ import { IPoint, IRect, ISize, RectExtensions } from '@foblex/2d';
import { IDraggableItem } from '../i-draggable-item';
import { EFResizeHandleType, FNodeBase } from '../../f-node';
import { FMediator } from '@foblex/mediator';
-import { GetNormalizedNodeRectRequest } from '../domain';
import { GetNodeResizeRestrictionsRequest, INodeResizeRestrictions } from './get-node-resize-restrictions';
import { ApplyChildResizeRestrictionsRequest } from './apply-child-resize-restrictions';
import { CalculateChangedSizeRequest } from './calculate-changed-size';
import { CalculateChangedPositionRequest } from './calculate-changed-position';
import { ApplyParentResizeRestrictionsRequest } from './apply-parent-resize-restrictions';
+import { GetNormalizedElementRectRequest } from '../../domain';
export class NodeResizeDragHandler implements IDraggableItem {
@@ -26,7 +26,7 @@ export class NodeResizeDragHandler implements IDraggableItem {
}
public prepareDragSequence(): void {
- this.originalRect = this.fMediator.send(new GetNormalizedNodeRectRequest(this.fNode));
+ this.originalRect = this.fMediator.send(new GetNormalizedElementRectRequest(this.fNode.hostElement));
this.restrictions = this.fMediator.send(new GetNodeResizeRestrictionsRequest(this.fNode, this.originalRect));
if (this.restrictions.childRect) {
diff --git a/projects/f-flow/src/f-draggable/node/create-move-nodes-drag-model-from-selection/create-move-nodes-drag-model-from-selection.execution.ts b/projects/f-flow/src/f-draggable/node/create-move-nodes-drag-model-from-selection/create-move-nodes-drag-model-from-selection.execution.ts
index a28c3ee..af696b4 100644
--- a/projects/f-flow/src/f-draggable/node/create-move-nodes-drag-model-from-selection/create-move-nodes-drag-model-from-selection.execution.ts
+++ b/projects/f-flow/src/f-draggable/node/create-move-nodes-drag-model-from-selection/create-move-nodes-drag-model-from-selection.execution.ts
@@ -1,4 +1,4 @@
-import { Injectable } from '@angular/core';
+import { inject, Injectable } from '@angular/core';
import { CreateMoveNodesDragModelFromSelectionRequest } from './create-move-nodes-drag-model-from-selection.request';
import { FExecutionRegister, FMediator, IExecution } from '@foblex/mediator';
import { FComponentsStore } from '../../../f-storage';
@@ -14,8 +14,8 @@ import {
PutInputConnectionHandlersToArrayRequest
} from './domain/put-input-connection-handlers-to-array';
import { NodeResizeByChildDragHandler } from '../node-resize-by-child.drag-handler';
-import { GetParentNodesRequest, IsArrayHasParentNodeRequest } from '../../domain';
-import { GetDeepChildrenNodesAndGroupsRequest } from '../../../domain';
+import { IsArrayHasParentNodeRequest } from '../../domain';
+import { GetDeepChildrenNodesAndGroupsRequest, GetParentNodesRequest } from '../../../domain';
import { flatMap } from '@foblex/utils';
@Injectable()
@@ -23,15 +23,14 @@ import { flatMap } from '@foblex/utils';
export class CreateMoveNodesDragModelFromSelectionExecution
implements IExecution {
- constructor(
- private fComponentsStore: FComponentsStore,
- private fDraggableDataContext: FDraggableDataContext,
- private fMediator: FMediator
- ) {
- }
+ private _fMediator = inject(FMediator);
+ private _fComponentsStore = inject(FComponentsStore);
+ private _fDraggableDataContext = inject(FDraggableDataContext);
public handle(request: CreateMoveNodesDragModelFromSelectionRequest): IDraggableItem[] {
- const itemsToDrag = this.getNodesWithRestrictions(this.getSelectedNodes(request.nodeWithDisabledSelection));
+ const itemsToDrag = this._getNodesWithRestrictions(
+ this._getSelectedNodes(request.nodeWithDisabledSelection)
+ );
return this.getDragHandlersWithConnections(
this.getDragHandlersFromNodes(itemsToDrag),
this.getAllOutputIds(itemsToDrag),
@@ -39,27 +38,31 @@ export class CreateMoveNodesDragModelFromSelectionExecution
);
}
- private getSelectedNodes(nodeWithDisabledSelection?: FNodeBase): FNodeBase[] {
- const result = this.fDraggableDataContext.selectedItems
- .map((x) => this._findNode(x.hostElement))
- .filter((x): x is FNodeBase => !!x);
+ private _getSelectedNodes(nodeWithDisabledSelection?: FNodeBase): FNodeBase[] {
+ const result = this._getNodesFromSelection();
if(nodeWithDisabledSelection) {
result.push(nodeWithDisabledSelection);
}
return result;
}
+ private _getNodesFromSelection(): FNodeBase[] {
+ return this._fDraggableDataContext.selectedItems
+ .map((x) => this._findNode(x.hostElement))
+ .filter((x): x is FNodeBase => !!x);
+ }
+
private _findNode(hostElement: HTMLElement | SVGElement): FNodeBase | undefined {
- return this.fComponentsStore.fNodes.find(n => n.isContains(hostElement));
+ return this._fComponentsStore.fNodes.find(n => n.isContains(hostElement));
}
- private getNodesWithRestrictions(selectedNodes: FNodeBase[]): INodeWithDistanceRestrictions[] {
+ private _getNodesWithRestrictions(nodesToDrag: FNodeBase[]): INodeWithDistanceRestrictions[] {
const result: INodeWithDistanceRestrictions[] = [];
- selectedNodes.forEach((x) => {
- const hasParentNodeInSelected = this.fMediator.send(new IsArrayHasParentNodeRequest(x, selectedNodes));
- const restrictions = this.fMediator.send(new GetNodeMoveRestrictionsRequest(x, hasParentNodeInSelected));
- const parentNodes = this.fMediator.send(new GetParentNodesRequest(x));
+ nodesToDrag.forEach((x) => {
+ const hasParentNodeInSelected = this._fMediator.send(new IsArrayHasParentNodeRequest(x, nodesToDrag));
+ const restrictions = this._fMediator.send(new GetNodeMoveRestrictionsRequest(x, hasParentNodeInSelected));
+ const parentNodes = this._fMediator.send(new GetParentNodesRequest(x));
result.push({ node: x, parentNodes, ...restrictions }, ...this.getChildrenItemsToDrag(x, restrictions));
});
@@ -71,7 +74,7 @@ export class CreateMoveNodesDragModelFromSelectionExecution
}
private getChildrenNodes(fId: string): FNodeBase[] {
- return this.fMediator.send(new GetDeepChildrenNodesAndGroupsRequest(fId));
+ return this._fMediator.send(new GetDeepChildrenNodesAndGroupsRequest(fId));
}
private getAllOutputIds(items: INodeWithDistanceRestrictions[]): string[] {
@@ -79,7 +82,7 @@ export class CreateMoveNodesDragModelFromSelectionExecution
}
private getOutputsForNode(node: FNodeBase): FConnectorBase[] {
- return this.fComponentsStore.fOutputs.filter((x) => node.isContains(x.hostElement));
+ return this._fComponentsStore.fOutputs.filter((x) => node.isContains(x.hostElement));
}
private getAllInputIds(items: INodeWithDistanceRestrictions[]): string[] {
@@ -87,7 +90,7 @@ export class CreateMoveNodesDragModelFromSelectionExecution
}
private getInputsForNode(node: FNodeBase): FConnectorBase[] {
- return this.fComponentsStore.fInputs.filter((x) => node.isContains(x.hostElement));
+ return this._fComponentsStore.fInputs.filter((x) => node.isContains(x.hostElement));
}
private getDragHandlersFromNodes(items: INodeWithDistanceRestrictions[]): IDraggableItem[] {
@@ -95,8 +98,8 @@ export class CreateMoveNodesDragModelFromSelectionExecution
items.forEach((node) => {
result.push(
- new NodeDragHandler(this.fDraggableDataContext, node.node, node.min, node.max),
- ...(node.parentNodes || []).map(() => new NodeResizeByChildDragHandler(this.fDraggableDataContext))
+ new NodeDragHandler(this._fDraggableDataContext, this._fComponentsStore, node.node, node.min, node.max),
+ ...(node.parentNodes || []).map(() => new NodeResizeByChildDragHandler(this._fDraggableDataContext))
);
});
return result;
@@ -107,8 +110,8 @@ export class CreateMoveNodesDragModelFromSelectionExecution
): IDraggableItem[] {
let result: IDraggableItem[] = handlers;
handlers.filter((x) => x instanceof NodeDragHandler).forEach((dragHandler) => {
- this.fMediator.send(new PutOutputConnectionHandlersToArrayRequest(dragHandler as NodeDragHandler, inputIds, result));
- this.fMediator.send(new PutInputConnectionHandlersToArrayRequest(dragHandler as NodeDragHandler, outputIds, result));
+ this._fMediator.send(new PutOutputConnectionHandlersToArrayRequest(dragHandler as NodeDragHandler, inputIds, result));
+ this._fMediator.send(new PutInputConnectionHandlersToArrayRequest(dragHandler as NodeDragHandler, outputIds, result));
});
return result;
}
diff --git a/projects/f-flow/src/f-draggable/node/create-move-nodes-drag-model-from-selection/domain/get-node-move-restrictions/get-node-move-restrictions.execution.ts b/projects/f-flow/src/f-draggable/node/create-move-nodes-drag-model-from-selection/domain/get-node-move-restrictions/get-node-move-restrictions.execution.ts
index 1849476..6950494 100644
--- a/projects/f-flow/src/f-draggable/node/create-move-nodes-drag-model-from-selection/domain/get-node-move-restrictions/get-node-move-restrictions.execution.ts
+++ b/projects/f-flow/src/f-draggable/node/create-move-nodes-drag-model-from-selection/domain/get-node-move-restrictions/get-node-move-restrictions.execution.ts
@@ -1,25 +1,23 @@
-import { Injectable } from '@angular/core';
+import { inject, Injectable } from '@angular/core';
import { GetNodeMoveRestrictionsRequest } from './get-node-move-restrictions.request';
import { IRect, PointExtensions } from '@foblex/2d';
import { INodeMoveRestrictions } from './i-node-move-restrictions';
import { FExecutionRegister, FMediator, IExecution } from '@foblex/mediator';
-import { GetNormalizedNodeRectRequest, GetNormalizedParentNodeRectRequest } from '../../../../domain';
+import { GetNormalizedParentNodeRectRequest } from '../../../../domain';
import { FNodeBase } from '../../../../../f-node';
+import { GetNormalizedElementRectRequest } from '../../../../../domain';
@Injectable()
@FExecutionRegister(GetNodeMoveRestrictionsRequest)
export class GetNodeMoveRestrictionsExecution
implements IExecution {
- constructor(
- private fMediator: FMediator
- ) {
- }
+ private _fMediator = inject(FMediator);
public handle(request: GetNodeMoveRestrictionsRequest): INodeMoveRestrictions {
if (request.fNode.fParentId && !request.hasParentNodeInSelected) {
const fParentNodeRect = this.getParentNodeRect(request.fNode);
- const fCurrentNodeRect = this.getCurrentNodeRect(request.fNode);
+ const fCurrentNodeRect = this._getNodeRect(request.fNode);
return {
min: PointExtensions.initialize(fParentNodeRect.x - fCurrentNodeRect.x, fParentNodeRect.y - fCurrentNodeRect.y),
max: PointExtensions.initialize(
@@ -31,12 +29,12 @@ export class GetNodeMoveRestrictionsExecution
return { ...DEFAULT_RESTRICTIONS };
}
- private getCurrentNodeRect(fNode: FNodeBase): IRect {
- return this.fMediator.send(new GetNormalizedNodeRectRequest(fNode));
+ private _getNodeRect(fNode: FNodeBase): IRect {
+ return this._fMediator.send(new GetNormalizedElementRectRequest(fNode.hostElement));
}
private getParentNodeRect(fNode: FNodeBase): IRect {
- return this.fMediator.send(new GetNormalizedParentNodeRectRequest(fNode));
+ return this._fMediator.send(new GetNormalizedParentNodeRectRequest(fNode));
}
}
diff --git a/projects/f-flow/src/f-draggable/node/node-move-finalize/node-move-finalize.execution.ts b/projects/f-flow/src/f-draggable/node/node-move-finalize/node-move-finalize.execution.ts
index f1e1376..4a9d34d 100644
--- a/projects/f-flow/src/f-draggable/node/node-move-finalize/node-move-finalize.execution.ts
+++ b/projects/f-flow/src/f-draggable/node/node-move-finalize/node-move-finalize.execution.ts
@@ -1,4 +1,4 @@
-import { Injectable } from '@angular/core';
+import { inject, Injectable } from '@angular/core';
import { NodeMoveFinalizeRequest } from './node-move-finalize.request';
import { IPoint, Point } from '@foblex/2d';
import { FExecutionRegister, FMediator, IExecution } from '@foblex/mediator';
@@ -6,50 +6,70 @@ import { FComponentsStore } from '../../../f-storage';
import { FDraggableDataContext } from '../../f-draggable-data-context';
import {
IsConnectionUnderNodeRequest
-} from '../../domain/is-connection-under-node/is-connection-under-node.request';
+} from '../../domain';
import { IDraggableItem } from '../../i-draggable-item';
import { NodeDragToParentDragHandler } from '../node-drag-to-parent.drag-handler';
+import { ILineAlignmentResult } from '../../../f-line-alignment';
+import { NodeDragHandler } from '../node.drag-handler';
@Injectable()
@FExecutionRegister(NodeMoveFinalizeRequest)
export class NodeMoveFinalizeExecution implements IExecution {
- private get flowHost(): HTMLElement {
- return this.fComponentsStore.fFlow!.hostElement;
- }
+ private _fMediator = inject(FMediator);
+ private _fComponentsStore = inject(FComponentsStore);
+ private _fDraggableDataContext = inject(FDraggableDataContext);
- constructor(
- private fComponentsStore: FComponentsStore,
- private fDraggableDataContext: FDraggableDataContext,
- private fMediator: FMediator
- ) {
+ private get _fHost(): HTMLElement {
+ return this._fComponentsStore.fFlow!.hostElement;
}
public handle(request: NodeMoveFinalizeRequest): void {
- const difference = this.getDifferenceWithLineAlignment(
- this.getDifferenceBetweenPreparationAndFinalize(request.event.getPosition())
+ const difference = this._getDifferenceWithLineAlignment(
+ this._getDifferenceBetweenPreparationAndFinalize(request.event.getPosition())
);
- this.getItems().forEach((x) => {
+
+ const firstNodeOrGroup = this._fDraggableDataContext.draggableItems
+ .find((x) => x instanceof NodeDragHandler)!;
+
+ const differenceWithCellSize = firstNodeOrGroup.getDifferenceWithCellSize(difference);
+
+ this._finalizeMove(differenceWithCellSize);
+
+ this._fMediator.send(new IsConnectionUnderNodeRequest());
+ this._fDraggableDataContext.fLineAlignment?.complete();
+ }
+
+ private _finalizeMove(difference: IPoint): void {
+ this._getItems().forEach((x) => {
x.onPointerMove({ ...difference });
x.onPointerUp?.();
});
- this.fMediator.send(new IsConnectionUnderNodeRequest());
- this.fDraggableDataContext.fLineAlignment?.complete();
}
- private getItems(): IDraggableItem[] {
- return this.fDraggableDataContext.draggableItems
+ private _getItems(): IDraggableItem[] {
+ return this._fDraggableDataContext.draggableItems
.filter((x) => !(x instanceof NodeDragToParentDragHandler));
}
- private getDifferenceBetweenPreparationAndFinalize(position: IPoint): Point {
- return Point.fromPoint(position).elementTransform(this.flowHost)
- .div(this.fDraggableDataContext.onPointerDownScale)
- .sub(this.fDraggableDataContext.onPointerDownPosition);
+ private _getDifferenceBetweenPreparationAndFinalize(position: IPoint): Point {
+ return Point.fromPoint(position).elementTransform(this._fHost)
+ .div(this._fDraggableDataContext.onPointerDownScale)
+ .sub(this._fDraggableDataContext.onPointerDownPosition);
+ }
+
+ private _getDifferenceWithLineAlignment(difference: IPoint): IPoint {
+ return this._applyLineAlignmentDifference(
+ difference,
+ this._getLineAlignmentDifference(difference)
+ );
+ }
+
+ private _getLineAlignmentDifference(difference: IPoint): ILineAlignmentResult | undefined {
+ return this._fDraggableDataContext.fLineAlignment?.findNearestCoordinate(difference);
}
- private getDifferenceWithLineAlignment(difference: IPoint): IPoint {
- const intersection = this.fDraggableDataContext.fLineAlignment?.findNearestCoordinate(difference);
+ private _applyLineAlignmentDifference(difference: IPoint, intersection: ILineAlignmentResult | undefined): IPoint {
if (intersection) {
difference.x = intersection.xResult.value ? (difference.x - intersection.xResult.distance!) : difference.x;
difference.y = intersection.yResult.value ? (difference.y - intersection.yResult.distance!) : difference.y;
diff --git a/projects/f-flow/src/f-draggable/node/node-move-preparation/node-move-preparation.execution.ts b/projects/f-flow/src/f-draggable/node/node-move-preparation/node-move-preparation.execution.ts
index 0f4e59c..a8f6fd1 100644
--- a/projects/f-flow/src/f-draggable/node/node-move-preparation/node-move-preparation.execution.ts
+++ b/projects/f-flow/src/f-draggable/node/node-move-preparation/node-move-preparation.execution.ts
@@ -1,4 +1,4 @@
-import { Injectable } from '@angular/core';
+import { inject, Injectable } from '@angular/core';
import { NodeMovePreparationRequest } from './node-move-preparation.request';
import { ITransformModel, Point } from '@foblex/2d';
import { FExecutionRegister, FMediator, IExecution } from '@foblex/mediator';
@@ -14,66 +14,68 @@ import { SelectAndUpdateNodeLayerRequest } from '../../../domain';
@FExecutionRegister(NodeMovePreparationRequest)
export class NodeMovePreparationExecution implements IExecution {
- private get transform(): ITransformModel {
- return this.fComponentsStore.fCanvas!.transform;
- }
+ private _fMediator = inject(FMediator);
+ private _fComponentsStore = inject(FComponentsStore);
+ private _fDraggableDataContext = inject(FDraggableDataContext);
- private get flowHost(): HTMLElement {
- return this.fComponentsStore.fFlow!.hostElement;
+ private get _transform(): ITransformModel {
+ return this._fComponentsStore.fCanvas!.transform;
}
- constructor(
- private fComponentsStore: FComponentsStore,
- private fDraggableDataContext: FDraggableDataContext,
- private fMediator: FMediator
- ) {
+ private get _fHost(): HTMLElement {
+ return this._fComponentsStore.fFlow!.hostElement;
}
public handle(request: NodeMovePreparationRequest): void {
- const node = this.getNode(request.event.targetElement);
- if (!node) {
- throw new Error('Node not found');
- }
- let itemsToDrag: IDraggableItem[] = [];
- if (!node.fSelectionDisabled) {
- this.selectAndUpdateNodeLayer(node);
- itemsToDrag = this.createDragModelFromSelection();
- } else {
- itemsToDrag = this.createDragModelFromSelection(node);
- }
- this.initializeLineAlignment(this.filterNodesFromDraggableItems(itemsToDrag));
+ const itemsToDrag = this._calculateDraggableItems(
+ this._getNode(request.event.targetElement)
+ );
+
+ this._initializeLineAlignment(itemsToDrag);
- this.fDraggableDataContext.onPointerDownScale = this.transform.scale;
- this.fDraggableDataContext.onPointerDownPosition = Point.fromPoint(request.event.getPosition())
- .elementTransform(this.flowHost).div(this.transform.scale);
- this.fDraggableDataContext.draggableItems = itemsToDrag;
+ this._fDraggableDataContext.onPointerDownScale = this._transform.scale;
+ this._fDraggableDataContext.onPointerDownPosition = Point.fromPoint(request.event.getPosition())
+ .elementTransform(this._fHost).div(this._transform.scale);
+ this._fDraggableDataContext.draggableItems = itemsToDrag;
}
- private selectAndUpdateNodeLayer(node: FNodeBase) {
- this.fMediator.send(
- new SelectAndUpdateNodeLayerRequest(node)
- );
+ private _getNode(targetElement: HTMLElement): FNodeBase {
+ const result = this._fComponentsStore.fNodes.find(n => n.isContains(targetElement))!;
+ if (!result) {
+ throw new Error('Node not found');
+ }
+ return result;
}
- private getNode(targetElement: HTMLElement): FNodeBase {
- return this.fComponentsStore.fNodes.find(n => n.isContains(targetElement))!;
+ //We drag nodes from selection model
+ private _calculateDraggableItems(fNode: FNodeBase): IDraggableItem[] {
+ let result: IDraggableItem[] = [];
+ if (!fNode.fSelectionDisabled) {
+ // Need to select node before drag
+ this._fMediator.send(new SelectAndUpdateNodeLayerRequest(fNode));
+
+ result = this._dragModelFromSelection();
+ } else {
+ // User can drag node that can't be selected
+ result = this._dragModelFromSelection(fNode);
+ }
+ return result;
}
- private createDragModelFromSelection(nodeWithDisabledSelection?: FNodeBase): IDraggableItem[] {
- return this.fMediator.send(
+ private _dragModelFromSelection(nodeWithDisabledSelection?: FNodeBase): IDraggableItem[] {
+ return this._fMediator.send(
new CreateMoveNodesDragModelFromSelectionRequest(nodeWithDisabledSelection)
);
}
- private initializeLineAlignment(nodesToDrag: FNodeBase[]): void {
- this.fDraggableDataContext.fLineAlignment?.initialize(
- this.fComponentsStore.fNodes,
- nodesToDrag
+ private _initializeLineAlignment(itemsToDrag: IDraggableItem[]): void {
+ this._fDraggableDataContext.fLineAlignment?.initialize(
+ this._fComponentsStore.fNodes, this._filterNodesFromDraggableItems(itemsToDrag)
);
}
- private filterNodesFromDraggableItems(items: IDraggableItem[]): FNodeBase[] {
+ private _filterNodesFromDraggableItems(items: IDraggableItem[]): FNodeBase[] {
return items.filter((x) => x instanceof NodeDragHandler)
.map(x => (x as NodeDragHandler).fNode);
}
diff --git a/projects/f-flow/src/f-draggable/node/node-move-preparation/node-move-preparation.validator.ts b/projects/f-flow/src/f-draggable/node/node-move-preparation/node-move-preparation.validator.ts
index f92941f..31a4a33 100644
--- a/projects/f-flow/src/f-draggable/node/node-move-preparation/node-move-preparation.validator.ts
+++ b/projects/f-flow/src/f-draggable/node/node-move-preparation/node-move-preparation.validator.ts
@@ -1,4 +1,4 @@
-import { Injectable } from '@angular/core';
+import { inject, Injectable } from '@angular/core';
import { NodeMovePreparationRequest } from './node-move-preparation.request';
import { FValidatorRegister, IValidator } from '@foblex/mediator';
import { FComponentsStore } from '../../../f-storage';
@@ -10,31 +10,28 @@ import { isClosestElementHasClass } from '@foblex/utils';
@FValidatorRegister(NodeMovePreparationRequest)
export class NodeMovePreparationValidator implements IValidator {
- constructor(
- private fComponentsStore: FComponentsStore,
- private fDraggableDataContext: FDraggableDataContext
- ) {
- }
+ private _fComponentsStore = inject(FComponentsStore);
+ private _fDraggableDataContext = inject(FDraggableDataContext);
public handle(request: NodeMovePreparationRequest): boolean {
- return this.isDragHandlesEmpty()
- && this.isDragHandleElement(request.event.targetElement)
- && this.isNodeCanBeDragged(this.getNode(request.event.targetElement));
+ return this._isDragHandlesEmpty()
+ && this._isDragHandleElement(request.event.targetElement)
+ && this._isNodeCanBeDragged(this._getNode(request.event.targetElement));
}
- private isDragHandlesEmpty(): boolean {
- return !this.fDraggableDataContext.draggableItems.length;
+ private _isDragHandlesEmpty(): boolean {
+ return !this._fDraggableDataContext.draggableItems.length;
}
- private getNode(targetElement: HTMLElement): FNodeBase | undefined {
- return this.fComponentsStore.fNodes.find(n => n.isContains(targetElement));
+ private _isDragHandleElement(element: HTMLElement): boolean {
+ return isClosestElementHasClass(element, '.f-drag-handle');
}
- private isNodeCanBeDragged(node: FNodeBase | undefined): boolean {
- return !!node && !node.fDraggingDisabled;
+ private _isNodeCanBeDragged(fNode: FNodeBase | undefined): boolean {
+ return !!fNode && !fNode.fDraggingDisabled;
}
- private isDragHandleElement(targetElement: HTMLElement): boolean {
- return isClosestElementHasClass(targetElement, '.f-drag-handle');
+ private _getNode(element: HTMLElement): FNodeBase | undefined {
+ return this._fComponentsStore.fNodes.find(x => x.isContains(element));
}
}
diff --git a/projects/f-flow/src/f-draggable/node/node.drag-handler.ts b/projects/f-flow/src/f-draggable/node/node.drag-handler.ts
index a1dd66e..b18de13 100644
--- a/projects/f-flow/src/f-draggable/node/node.drag-handler.ts
+++ b/projects/f-flow/src/f-draggable/node/node.drag-handler.ts
@@ -5,39 +5,41 @@ import { FNodeBase } from '../../f-node';
import {
INodeMoveRestrictions
} from './create-move-nodes-drag-model-from-selection';
+import { FComponentsStore } from '../../f-storage';
export class NodeDragHandler implements IDraggableItem {
- private onPointerDownPosition: IPoint = PointExtensions.initialize();
+ private readonly _onPointerDownPosition = PointExtensions.initialize();
constructor(
private fDraggableDataContext: FDraggableDataContext,
+ private fComponentsStore: FComponentsStore,
public fNode: FNodeBase,
public minDistance: IPoint,
public maxDistance: IPoint,
) {
- this.onPointerDownPosition = { ...fNode.position };
+ this._onPointerDownPosition = { ...fNode.position };
}
public onPointerMove(difference: IPoint): void {
- const restrictedDifference = this.getDifference(difference, { min: this.minDistance, max: this.maxDistance });
+ const restrictedDifference = this._getDifference(difference, { min: this.minDistance, max: this.maxDistance });
- this.redrawNode(this.getNewPosition(restrictedDifference));
+ this._redraw(this._getPosition(restrictedDifference));
this.fDraggableDataContext.fLineAlignment?.handle(restrictedDifference);
}
- private getNewPosition(difference: IPoint): IPoint {
- return Point.fromPoint(this.onPointerDownPosition).add(difference);
+ private _getPosition(difference: IPoint): IPoint {
+ return Point.fromPoint(this._onPointerDownPosition).add(difference);
}
- private getDifference(difference: IPoint, restrictions: INodeMoveRestrictions): IPoint {
+ private _getDifference(difference: IPoint, restrictions: INodeMoveRestrictions): IPoint {
return {
x: Math.min(Math.max(difference.x, restrictions.min.x), restrictions.max.x),
y: Math.min(Math.max(difference.y, restrictions.min.y), restrictions.max.y)
}
}
- private redrawNode(position: IPoint): void {
+ private _redraw(position: IPoint): void {
this.fNode.updatePosition(position);
this.fNode.redraw();
}
@@ -45,4 +47,20 @@ export class NodeDragHandler implements IDraggableItem {
public onPointerUp(): void {
this.fNode.positionChange.emit(this.fNode.position);
}
+
+ public getDifferenceWithCellSize(difference: IPoint): IPoint {
+ const restrictedDifference = this._getDifference(difference, { min: this.minDistance, max: this.maxDistance });
+ const position = this._getPosition(restrictedDifference);
+
+ return Point.fromPoint(this._applyCellSize(position)).sub(this._onPointerDownPosition);
+ }
+
+ private _applyCellSize(position: IPoint): IPoint {
+ const hCellSize = this.fComponentsStore.fDraggable!.hCellSize;
+ const vCellSize = this.fComponentsStore.fDraggable!.vCellSize;
+ return {
+ x: Math.round(position.x / hCellSize) * hCellSize,
+ y: Math.round(position.y / vCellSize) * vCellSize
+ };
+ }
}
diff --git a/projects/f-flow/src/f-node/domain/index.ts b/projects/f-flow/src/f-node/domain/index.ts
deleted file mode 100644
index 1760961..0000000
--- a/projects/f-flow/src/f-node/domain/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export * from './is-node';
diff --git a/projects/f-flow/src/f-node/f-drag-handle/f-drag-handle.directive.ts b/projects/f-flow/src/f-node/f-drag-handle.directive.ts
similarity index 90%
rename from projects/f-flow/src/f-node/f-drag-handle/f-drag-handle.directive.ts
rename to projects/f-flow/src/f-node/f-drag-handle.directive.ts
index 59f1afe..5ee63bc 100644
--- a/projects/f-flow/src/f-node/f-drag-handle/f-drag-handle.directive.ts
+++ b/projects/f-flow/src/f-node/f-drag-handle.directive.ts
@@ -1,7 +1,7 @@
import {
Directive, ElementRef, inject, InjectionToken
} from "@angular/core";
-import { IHasHostElement } from '../../i-has-host-element';
+import { IHasHostElement } from '../i-has-host-element';
export const F_DRAG_HANDLE = new InjectionToken('F_DRAG_HANDLE');
diff --git a/projects/f-flow/src/f-node/f-drag-handle/index.ts b/projects/f-flow/src/f-node/f-drag-handle/index.ts
deleted file mode 100644
index fc5f5d6..0000000
--- a/projects/f-flow/src/f-node/f-drag-handle/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export * from './f-drag-handle.directive';
diff --git a/projects/f-flow/src/f-node/index.ts b/projects/f-flow/src/f-node/index.ts
index 2ebbf99..be9c61f 100644
--- a/projects/f-flow/src/f-node/index.ts
+++ b/projects/f-flow/src/f-node/index.ts
@@ -1,17 +1,17 @@
-export * from './domain';
-
-export * from './f-drag-handle';
-
export * from './f-resize-handle';
export * from './f-rotate-handle';
+export * from './f-drag-handle.directive';
+
export * from './f-group.directive';
export * from './f-node.directive';
export * from './f-node-base';
+export * from './is-node';
+
export * from './providers';
diff --git a/projects/f-flow/src/f-node/domain/is-node.ts b/projects/f-flow/src/f-node/is-node.ts
similarity index 100%
rename from projects/f-flow/src/f-node/domain/is-node.ts
rename to projects/f-flow/src/f-node/is-node.ts
diff --git a/projects/f-flow/src/f-node/providers.ts b/projects/f-flow/src/f-node/providers.ts
index c571063..899ded7 100644
--- a/projects/f-flow/src/f-node/providers.ts
+++ b/projects/f-flow/src/f-node/providers.ts
@@ -1,7 +1,7 @@
import { FNodeDirective } from './f-node.directive';
-import { FDragHandleDirective } from './f-drag-handle';
import { FResizeHandleDirective } from './f-resize-handle';
import { FGroupDirective } from './f-group.directive';
+import { FDragHandleDirective } from './f-drag-handle.directive';
export const F_NODE_PROVIDERS = [
diff --git a/public/markdown/examples/environment.ts b/public/markdown/examples/environment.ts
index 9f394c4..44b0208 100644
--- a/public/markdown/examples/environment.ts
+++ b/public/markdown/examples/environment.ts
@@ -176,6 +176,10 @@ function createEnvironment(): IDocsEnvironment {
tag: 'tournament-bracket',
component: import('../../../projects/f-pro-examples/tournament-bracket/tournament-bracket.component')
},
+ {
+ tag: 'grid-system-example',
+ component: import('../../../projects/f-examples/extensions/grid-system-example/grid-system-example.component')
+ }
],
socialLinks: [
{ icon: 'github', link: 'https://github.com/Foblex/f-flow' },
@@ -545,6 +549,20 @@ function extensionGroup(): INavigationGroup {
image_height: 600,
image_type: 'image/png',
},
+ {
+ link: 'grid-system',
+ text: 'Grid System',
+ description: 'Add a grid system to Foblex Flow diagrams for Angular.',
+ image: './previews/examples/grid-system-example.light.png',
+ image_dark: './previews/examples/grid-system-example.dark.png',
+ image_width: 821,
+ image_height: 600,
+ image_type: 'image/png',
+ badge: {
+ text: 'New',
+ type: 'info'
+ }
+ },
{
link: 'minimap',
text: 'Minimap',
diff --git a/public/markdown/examples/grid-system.md b/public/markdown/examples/grid-system.md
new file mode 100644
index 0000000..a72ddcd
--- /dev/null
+++ b/public/markdown/examples/grid-system.md
@@ -0,0 +1,21 @@
+# Grid System
+
+## Description
+
+This guide demonstrates how to position nodes in a grid system using Foblex Flow for Angular. To enable the grid system, you need to parameterize the [fDraggable](./docs/f-draggable-directive) directive with the grid properties `[vCellSize]` and `[hCellSize]`.
+
+- `[vCellSize]`: Defines the vertical size of each grid cell.
+- `[hCellSize]`: Defines the horizontal size of each grid cell.
+
+## Example
+
+::: ng-component [height]="600"
+[component.html] <<< https://raw.githubusercontent.com/Foblex/f-flow/main/projects/f-examples/extensions/grid-system-example/grid-system-example.component.html
+[component.ts] <<< https://raw.githubusercontent.com/Foblex/f-flow/main/projects/f-examples/extensions/grid-system-example/grid-system-example.component.ts
+[component.scss] <<< https://raw.githubusercontent.com/Foblex/f-flow/main/projects/f-examples/extensions/grid-system-example/grid-system-example.component.scss
+[common.scss] <<< https://raw.githubusercontent.com/Foblex/f-flow/main/projects/f-examples/_flow-common.scss
+:::
+
+
+
+
diff --git a/public/markdown/guides/f-draggable-directive.md b/public/markdown/guides/f-draggable-directive.md
index 9ef3cd4..5a56a7d 100644
--- a/public/markdown/guides/f-draggable-directive.md
+++ b/public/markdown/guides/f-draggable-directive.md
@@ -6,7 +6,11 @@ The **FDraggableDirective** enhances a component, typically a flow [f-flow](f-fl
## Inputs
- - `fDraggableDisabled: boolean;` Determines whether the draggable functionality is disabled. Default: `false
+ - `fDraggableDisabled: boolean;` Determines whether the draggable functionality is disabled. Default: `false`.
+
+ - `vCellSize: number;` Defines the vertical size of each grid cell. Default: `1`.
+
+ - `hCellSize: number;` Defines the horizontal size of each grid cell. Default: `1`.
## Outputs
diff --git a/public/previews/examples/grid-system-example.dark.png b/public/previews/examples/grid-system-example.dark.png
new file mode 100644
index 0000000..550f760
Binary files /dev/null and b/public/previews/examples/grid-system-example.dark.png differ
diff --git a/public/previews/examples/grid-system-example.light.png b/public/previews/examples/grid-system-example.light.png
new file mode 100644
index 0000000..6923e49
Binary files /dev/null and b/public/previews/examples/grid-system-example.light.png differ