Skip to content

Commit

Permalink
docs: Added resize handle example
Browse files Browse the repository at this point in the history
  • Loading branch information
siarheihuzarevich committed Sep 24, 2024
1 parent 8fb4399 commit 4f23af5
Show file tree
Hide file tree
Showing 16 changed files with 178 additions and 30 deletions.
3 changes: 1 addition & 2 deletions projects/f-examples/_flow-common.scss
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@
}

@mixin node {
padding: 4px;
padding: 24px;
color: var(--node-color);
text-align: center;
background: var(--node-background-color);
Expand All @@ -129,7 +129,6 @@

@mixin connectors {


.connectors-line {
position: absolute;
display: flex;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
.simple-node {
@include flow-common.node;
width: unset;
padding: 24px;
}

img {
Expand Down
10 changes: 5 additions & 5 deletions projects/f-examples/drag-handle/drag-handle.component.html
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
<f-flow fDraggable (fLoaded)="onLoaded()">
<f-canvas fZoom>
<f-canvas>
<div fNode fDragHandle
[fNodePosition]="{ x: 24, y: 24 }">
[fNodePosition]="{ x: 0, y: 0 }">
Node is the drag handle
</div>

<div fNode
[fNodePosition]="{ x: 164, y: 84 }" class="drag-handle-inside">
[fNodePosition]="{ x: 120, y: 100 }" class="drag-handle-inside">
<span fDragHandle class="f-icon f-drag-handle-icon"></span>
Only the icon is the drag handle
</div>

<div fNode
[fNodePosition]="{ x: 304, y: 24 }" class="drag-handle-outside">
[fNodePosition]="{ x: 350, y: 0 }" class="drag-handle-outside">
<div fDragHandle>
<span class="f-icon f-drag-handle-icon"></span>
</div>
Only the icon is the drag handle
</div>

<div fNode
[fNodePosition]="{ x: 150, y: 170 }">
[fNodePosition]="{ x: 130, y: 200 }">
Only the image is the drag handle
<div fDragHandle>
<img src="https://material.angular.io/assets/img/examples/shiba2.jpg">
Expand Down
2 changes: 1 addition & 1 deletion projects/f-examples/drag-handle/drag-handle.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,6 @@ export class DragHandleComponent {
public fCanvas!: FCanvasComponent;

public onLoaded(): void {
this.fCanvas.fitToScreen(PointExtensions.initialize(100, 100), false);
this.fCanvas.resetScaleAndCenter(false);
}
}
46 changes: 46 additions & 0 deletions projects/f-examples/resize-handle/resize-handle.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<f-flow fDraggable (fLoaded)="onLoaded()">
<f-canvas>
<div fNode fDragHandle
[fNodePosition]="{ x: 0, y: 0 }">
<div fResizeHandle [fResizeHandleType]="eResizeHandleType.LEFT_TOP"></div>
<div class="node-content">
Node with Left Top ResizeHandle
</div>
</div>

<div fNode fDragHandle
[fNodePosition]="{ x: 350, y: 0 }">
<div fResizeHandle [fResizeHandleType]="eResizeHandleType.RIGHT_TOP"></div>
<div class="node-content">
Node with Right Top ResizeHandle
</div>
</div>

<div fNode fDragHandle
[fNodePosition]="{ x: 0, y: 100 }">
<div fResizeHandle [fResizeHandleType]="eResizeHandleType.RIGHT_BOTTOM"></div>
<div class="node-content">
Node with Right Bottom ResizeHandle
</div>
</div>

<div fNode fDragHandle
[fNodePosition]="{ x: 350, y: 100 }">
<div fResizeHandle [fResizeHandleType]="eResizeHandleType.LEFT_BOTTOM"></div>
<div class="node-content">
Node with Left Bottom ResizeHandle
</div>
</div>

<div fNode fDragHandle
[fNodePosition]="{ x: 50, y: 200 }">
<div fResizeHandle [fResizeHandleType]="eResizeHandleType.LEFT_TOP"></div>
<div fResizeHandle [fResizeHandleType]="eResizeHandleType.RIGHT_TOP"></div>
<div fResizeHandle [fResizeHandleType]="eResizeHandleType.LEFT_BOTTOM"></div>
<div fResizeHandle [fResizeHandleType]="eResizeHandleType.RIGHT_BOTTOM"></div>
<div class="node-content">
Node with all ResizeHandles
</div>
</div>
</f-canvas>
</f-flow>
51 changes: 51 additions & 0 deletions projects/f-examples/resize-handle/resize-handle.component.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
@use "../flow-common";

::ng-deep resize-handle {
@include flow-common.connection;
}

.f-node {
position: relative;
@include flow-common.node;
padding: 24px;
}

.node-content {
width: 100%;
height: 100%;
overflow: auto;
}

.f-resize-handle {
// z-index: 10;
overflow: visible;
position: absolute;
width: 12px;
height: 12px;
background-color: var(--node-background-color);
border: 1px solid var(--node-border-color);

&.f-resize-handle-left-top {
top: -6px;
left: -6px;
cursor: nwse-resize;
}

&.f-resize-handle-right-top {
top: -6px;
right: -6px;
cursor: nesw-resize;
}

&.f-resize-handle-left-bottom {
bottom: -6px;
left: -6px;
cursor: nesw-resize;
}

&.f-resize-handle-right-bottom {
bottom: -6px;
right: -6px;
cursor: nwse-resize;
}
}
28 changes: 28 additions & 0 deletions projects/f-examples/resize-handle/resize-handle.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { ChangeDetectionStrategy, Component, ViewChild } from '@angular/core';
import {
EFResizeHandleType,
FCanvasComponent,
FFlowModule
} from '@foblex/flow';

@Component({
selector: 'resize-handle',
styleUrls: [ './resize-handle.component.scss' ],
templateUrl: './resize-handle.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
standalone: true,
imports: [
FFlowModule,
]
})
export class ResizeHandleComponent {

@ViewChild(FCanvasComponent, { static: true })
public fCanvas!: FCanvasComponent;

public onLoaded(): void {
this.fCanvas.resetScaleAndCenter(false);
}

protected readonly eResizeHandleType = EFResizeHandleType;
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ export class ApplyChildResizeRestrictionsRequest {

constructor(
public rect: IRect,
public restrictionsRect: IRect,
public restrictionsRect: IRect
) {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@ export class CalculateChangedSizeExecution
implements IExecution<CalculateChangedSizeRequest, IRect> {

public handle(request: CalculateChangedSizeRequest): IRect {
return this.change(request.originalRect, request.difference, RESIZE_DIRECTIONS[request.fResizeHandleType]);
return this.change(
request.originalRect,
request.difference,
RESIZE_DIRECTIONS[request.fResizeHandleType],
);
}

private change(rect: IRect, difference: IPoint, direction: IPoint): IRect {
Expand All @@ -20,6 +24,7 @@ export class CalculateChangedSizeExecution
rect.height + direction.y * difference.y
);


if (result.width < 0) {
result.x = result.width;
result.width = Math.abs(result.width);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { Injectable } from '@angular/core';
import { GetNodeResizeRestrictionsRequest } from './get-node-resize-restrictions.request';
import { IRect } from '@foblex/2d';
import { IRect, SizeExtensions } from '@foblex/2d';
import { INodeResizeRestrictions } from './i-node-resize-restrictions';
import { FExecutionRegister, FMediator, IExecution } from '@foblex/mediator';
import { GetNormalizedParentNodeRectRequest } from '../../domain';
import { GetNodePaddingRequest, GetNormalizedParentNodeRectRequest } from '../../domain';
import { GetNormalizedChildrenNodesRectRequest } from '../get-normalized-children-nodes-rect';
import { FNodeBase } from '../../../f-node';


@Injectable()
Expand All @@ -18,12 +19,18 @@ export class GetNodeResizeRestrictionsExecution
}

public handle(request: GetNodeResizeRestrictionsRequest): INodeResizeRestrictions {
const childRect = this.fMediator.send<IRect | null>(new GetNormalizedChildrenNodesRectRequest(request.fNode, request.rect));
const fNodePaddings = this.getNodePaddings(request.fNode, request.rect);
const childRect = this.fMediator.send<IRect | null>(new GetNormalizedChildrenNodesRectRequest(request.fNode, fNodePaddings));
const parentRect = this.fMediator.send<IRect>(new GetNormalizedParentNodeRectRequest(request.fNode));

return {
parentRect,
childRect,
minSize: SizeExtensions.initialize(fNodePaddings[0] + fNodePaddings[2], fNodePaddings[1] + fNodePaddings[3])
}
}

private getNodePaddings(node: FNodeBase, rect: IRect): [ number, number, number, number ] {
return this.fMediator.send<[ number, number, number, number ]>(new GetNodePaddingRequest(node, rect));
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { IRect } from '@foblex/2d';
import { IRect, ISize } from '@foblex/2d';

export interface INodeResizeRestrictions {

parentRect: IRect;

childRect: IRect | null;

minSize: ISize;
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +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 { GetNodePaddingRequest, GetNormalizedNodeRectRequest } from '../../domain';
import { GetNormalizedNodeRectRequest } from '../../domain';
import { GetDeepChildrenNodesAndGroupsRequest } from '../../../domain';

@Injectable()
Expand All @@ -21,9 +21,7 @@ export class GetNormalizedChildrenNodesRectExecution
this.getChildrenNodes(request.fNode.fId).map((x) => this.normalizeRect(x))
);
return childNodeRect ?
this.concatRectWithParentPadding(childNodeRect,
this.getNodePadding(request.fNode, request.rect)
) : null;
this.concatRectWithParentPadding(childNodeRect, request.paddings) : null;
}

private getChildrenNodes(fId: string): FNodeBase[] {
Expand All @@ -34,10 +32,6 @@ export class GetNormalizedChildrenNodesRectExecution
return this.fMediator.send<IRect>(new GetNormalizedNodeRectRequest(node));
}

private getNodePadding(node: FNodeBase, rect: IRect): [ number, number, number, number ] {
return this.fMediator.send<[ number, number, number, number ]>(new GetNodePaddingRequest(node, rect));
}

private concatRectWithParentPadding(rect: IRect, padding: [ number, number, number, number ]): IRect {
return RectExtensions.initialize(
rect.x - padding[0],
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import { FNodeBase } from '../../../f-node';
import { IRect } from '@foblex/2d';

export class GetNormalizedChildrenNodesRectRequest {

constructor(
public fNode: FNodeBase,
public rect: IRect
public paddings: [ number, number, number, number ]
) {
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { IPoint, IRect, RectExtensions } from '@foblex/2d';
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';
Expand All @@ -15,7 +15,8 @@ export class NodeResizeDragHandler implements IDraggableItem {

private restrictions!: INodeResizeRestrictions;

private childRestrictions: (rect: IRect, restrictionsRect: IRect) => void = () => {};
private childRestrictions: (rect: IRect, restrictionsRect: IRect) => void = () => {
};

constructor(
private fMediator: FMediator,
Expand All @@ -28,15 +29,15 @@ export class NodeResizeDragHandler implements IDraggableItem {
this.originalRect = this.fMediator.send<IRect>(new GetNormalizedNodeRectRequest(this.fNode));

this.restrictions = this.fMediator.send<INodeResizeRestrictions>(new GetNodeResizeRestrictionsRequest(this.fNode, this.originalRect));
if(this.restrictions.childRect) {
if (this.restrictions.childRect) {
this.childRestrictions = (rect: IRect, restrictionsRect: IRect) => {
this.applyChildRestrictions(rect, restrictionsRect);
};
}
}

public move(difference: IPoint): void {
const changedRect = this.changePosition(difference, this.changeSize(difference));
const changedRect = this.changePosition(difference, this.changeSize(difference, this.restrictions.minSize));

this.childRestrictions(changedRect, this.restrictions.childRect!);
this.applyParentRestrictions(changedRect, this.restrictions.parentRect);
Expand All @@ -46,7 +47,7 @@ export class NodeResizeDragHandler implements IDraggableItem {
this.fNode.redraw();
}

private changeSize(difference: IPoint): IRect {
private changeSize(difference: IPoint, minSize: ISize): IRect {
return this.fMediator.send<IRect>(
new CalculateChangedSizeRequest(this.originalRect, difference, this.fResizeHandleType)
);
Expand Down
1 change: 1 addition & 0 deletions public/docs/en/examples/environment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ function createEnvironment(): IDocsEnvironment {
components: [
{ tag: 'custom-nodes', component: import('../../../../projects/f-examples/custom-nodes/custom-nodes.component') },
{ tag: 'drag-handle', component: import('../../../../projects/f-examples/drag-handle/drag-handle.component') },
{ tag: 'resize-handle', component: import('../../../../projects/f-examples/resize-handle/resize-handle.component') },
{ tag: 'draggable-flow', component: import('../../../../projects/f-guides-examples/draggable-flow/draggable-flow.component') },
{ tag: 'vp-flow', component: import('../../../../projects/f-pro-examples/visual-programming/components/flow/vp-flow.component') },
{ tag: 'db-management-flow', component: import('../../../../projects/f-pro-examples/db-management-example/components/flow/db-management-flow.component') },
Expand Down
16 changes: 16 additions & 0 deletions public/docs/en/examples/resize-handle.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Resize Handle

## Description

Learn how to enhance the interactivity of your flow diagrams by adding a [ResizeHandle](./docs/f-resize-handle-directive) to nodes. This example demonstrates the process of making nodes dynamically resizable, allowing users to easily modify the dimensions of nodes within an Angular application powered by Foblex Flow.

## Example

::: ng-component <resize-handle></resize-handle> [height]="600"
[component.html] <<< https://raw.githubusercontent.com/Foblex/f-flow/main/projects/f-examples/resize-handle/resize-handle.component.html
[component.ts] <<< https://raw.githubusercontent.com/Foblex/f-flow/main/projects/f-examples/resize-handle/resize-handle.component.ts
[component.scss] <<< https://raw.githubusercontent.com/Foblex/f-flow/main/projects/f-examples/resize-handle/resize-handle.component.scss
[common.scss] <<< https://raw.githubusercontent.com/Foblex/f-flow/main/projects/f-examples/_flow-common.scss
:::


0 comments on commit 4f23af5

Please sign in to comment.