178 lines
5.1 KiB
ObjectPascal
178 lines
5.1 KiB
ObjectPascal
unit Myc.Fmx.AstEditor.Handlers.Pipes;
|
|
|
|
interface
|
|
|
|
uses
|
|
System.SysUtils,
|
|
System.UITypes,
|
|
System.Types,
|
|
Myc.Ast,
|
|
Myc.Ast.Nodes,
|
|
Myc.Fmx.AstEditor.Render,
|
|
Myc.Fmx.AstEditor.Node,
|
|
Myc.Fmx.AstEditor.Handlers;
|
|
|
|
type
|
|
// --- Pipe Container ---
|
|
|
|
TPipeNodeHandler = class(TBaseNodeHandler<IPipeNode>)
|
|
private
|
|
FInputsNode: TAstViewNode;
|
|
FTransformNode: TAstViewNode;
|
|
public
|
|
procedure BuildUI(OwnerNode: TAstViewNode); override;
|
|
function ReconstructAst(OwnerNode: TAstViewNode): IAstNode; override;
|
|
end;
|
|
|
|
// --- Pipe Inputs ---
|
|
|
|
TPipeInputListHandler = class(TNodeListHandler<IPipeInputNode>)
|
|
protected
|
|
function GetOrientation: TLayoutOrientation; override;
|
|
function GetAlignment: TLayoutAlignment; override;
|
|
public
|
|
function ReconstructAst(OwnerNode: TAstViewNode): IAstNode; override;
|
|
end;
|
|
|
|
TPipeInputNodeHandler = class(TBaseNodeHandler<IPipeInputNode>)
|
|
private
|
|
FStreamNode: TAstViewNode;
|
|
FSelectorsNode: TAstViewNode;
|
|
public
|
|
procedure BuildUI(OwnerNode: TAstViewNode); override;
|
|
function ReconstructAst(OwnerNode: TAstViewNode): IAstNode; override;
|
|
end;
|
|
|
|
// --- Selectors ---
|
|
|
|
TPipeSelectorListHandler = class(TNodeListHandler<IKeywordNode>)
|
|
protected
|
|
function GetOrientation: TLayoutOrientation; override;
|
|
public
|
|
function ReconstructAst(OwnerNode: TAstViewNode): IAstNode; override;
|
|
end;
|
|
|
|
implementation
|
|
|
|
{ TPipeNodeHandler }
|
|
|
|
procedure TPipeNodeHandler.BuildUI(OwnerNode: TAstViewNode);
|
|
var
|
|
visu: IAstVisualizer;
|
|
header: TTextNode;
|
|
arrow: TTextNode;
|
|
begin
|
|
visu := OwnerNode.Visualizer.Clone(OwnerNode, OwnerNode.Visualizer.ExprDepth + 1);
|
|
|
|
OwnerNode.Frameless := False;
|
|
OwnerNode.Orientation := loVertical;
|
|
OwnerNode.Alignment := laCenter;
|
|
|
|
// Distinct background color for Pipes to make them stand out as data flows
|
|
OwnerNode.BackgroundColor := $FF202530;
|
|
OwnerNode.BorderColor := TAlphaColors.Slateblue;
|
|
|
|
// Header
|
|
header := OwnerNode.AddLabel(OwnerNode, 'Pipe Pipeline');
|
|
header.FontSettings.Font.Style := [TFontStyle.fsBold];
|
|
header.Color := TAlphaColors.Lightskyblue;
|
|
|
|
// Section 1: Inputs
|
|
FInputsNode := visu.CallAccept(FNode.Inputs);
|
|
|
|
// Visual Separator / Direction indicator
|
|
arrow := OwnerNode.AddLabel(OwnerNode, '▼ Transform ▼');
|
|
arrow.FontSettings.Font.Size := 10;
|
|
arrow.Color := TAlphaColors.Gray;
|
|
arrow.Margins := TMarginRect.Create(0, 5, 0, 5);
|
|
|
|
// Section 2: Transformation (Lambda)
|
|
FTransformNode := visu.CallAccept(FNode.Transformation);
|
|
end;
|
|
|
|
function TPipeNodeHandler.ReconstructAst(OwnerNode: TAstViewNode): IAstNode;
|
|
begin
|
|
Result :=
|
|
TAst.Pipe(FNode.Identity, FInputsNode.CreateAst.AsPipeInputList, FTransformNode.CreateAst.AsLambdaExpression, FNode.StaticType);
|
|
end;
|
|
|
|
{ TPipeInputListHandler }
|
|
|
|
function TPipeInputListHandler.GetOrientation: TLayoutOrientation;
|
|
begin
|
|
// Stack inputs vertically
|
|
Result := loVertical;
|
|
end;
|
|
|
|
function TPipeInputListHandler.GetAlignment: TLayoutAlignment;
|
|
begin
|
|
Result := laFlush;
|
|
end;
|
|
|
|
function TPipeInputListHandler.ReconstructAst(OwnerNode: TAstViewNode): IAstNode;
|
|
var
|
|
arr: TArray<IPipeInputNode>;
|
|
i: Integer;
|
|
begin
|
|
SetLength(arr, FChildNodes.Count);
|
|
for i := 0 to FChildNodes.Count - 1 do
|
|
arr[i] := FChildNodes[i].CreateAst.AsPipeInput;
|
|
|
|
Result := TPipeInputList.Create(arr, FNode.Identity);
|
|
end;
|
|
|
|
{ TPipeInputNodeHandler }
|
|
|
|
procedure TPipeInputNodeHandler.BuildUI(OwnerNode: TAstViewNode);
|
|
var
|
|
visu: IAstVisualizer;
|
|
begin
|
|
visu := OwnerNode.Visualizer.Clone(OwnerNode, OwnerNode.Visualizer.ExprDepth);
|
|
|
|
OwnerNode.Frameless := True;
|
|
OwnerNode.Orientation := loHorizontal;
|
|
OwnerNode.Alignment := laCenter;
|
|
|
|
// "StreamName [ :Col :Col ]"
|
|
FStreamNode := visu.CallAccept(FNode.StreamSource);
|
|
|
|
// Add small spacing
|
|
var spacer := TAutoFitLayout.Create(OwnerNode.Host);
|
|
spacer.Size := TSizeF.Create(5, 5);
|
|
OwnerNode.AddChild(spacer);
|
|
|
|
FSelectorsNode := visu.CallAccept(FNode.Selectors);
|
|
end;
|
|
|
|
function TPipeInputNodeHandler.ReconstructAst(OwnerNode: TAstViewNode): IAstNode;
|
|
begin
|
|
Result :=
|
|
TAst.PipeInput(
|
|
FNode.StreamSource, // Identifiers are immutable usually, or re-create if needed
|
|
FSelectorsNode.CreateAst.AsPipeSelectorList,
|
|
FNode.Identity.Location
|
|
);
|
|
end;
|
|
|
|
{ TPipeSelectorListHandler }
|
|
|
|
function TPipeSelectorListHandler.GetOrientation: TLayoutOrientation;
|
|
begin
|
|
// Selectors are horizontal: [:A :B :C]
|
|
Result := loHorizontal;
|
|
end;
|
|
|
|
function TPipeSelectorListHandler.ReconstructAst(OwnerNode: TAstViewNode): IAstNode;
|
|
var
|
|
arr: TArray<IKeywordNode>;
|
|
i: Integer;
|
|
begin
|
|
SetLength(arr, FChildNodes.Count);
|
|
for i := 0 to FChildNodes.Count - 1 do
|
|
arr[i] := FChildNodes[i].CreateAst.AsKeyword;
|
|
|
|
Result := TPipeSelectorList.Create(arr, FNode.Identity);
|
|
end;
|
|
|
|
end.
|