New visualizer

This commit is contained in:
Michael Schimmel
2025-10-26 18:06:45 +01:00
parent e379e6694c
commit e95a920dc7
9 changed files with 1489 additions and 1589 deletions
File diff suppressed because one or more lines are too long
+2 -2
View File
@@ -8,7 +8,6 @@ uses
Myc.Ast.Evaluator in '..\Src\AST\Myc.Ast.Evaluator.pas', Myc.Ast.Evaluator in '..\Src\AST\Myc.Ast.Evaluator.pas',
Myc.Ast.Nodes in '..\Src\AST\Myc.Ast.Nodes.pas', Myc.Ast.Nodes in '..\Src\AST\Myc.Ast.Nodes.pas',
Myc.Ast.Scope in '..\Src\AST\Myc.Ast.Scope.pas', Myc.Ast.Scope in '..\Src\AST\Myc.Ast.Scope.pas',
Myc.Fmx.AstEditor in 'Myc.Fmx.AstEditor.pas',
Myc.Data.Value in 'Myc.Data.Value.pas', Myc.Data.Value in 'Myc.Data.Value.pas',
Myc.Ast.Debugger in '..\Src\AST\Myc.Ast.Debugger.pas', Myc.Ast.Debugger in '..\Src\AST\Myc.Ast.Debugger.pas',
Myc.Ast.Visitor in '..\Src\AST\Myc.Ast.Visitor.pas', Myc.Ast.Visitor in '..\Src\AST\Myc.Ast.Visitor.pas',
@@ -21,7 +20,8 @@ uses
Myc.Fmx.AstEditor.Text in 'Myc.Fmx.AstEditor.Text.pas', Myc.Fmx.AstEditor.Text in 'Myc.Fmx.AstEditor.Text.pas',
Myc.Utils in '..\Src\Myc.Utils.pas', Myc.Utils in '..\Src\Myc.Utils.pas',
Myc.Ast.Script in '..\Src\AST\Myc.Ast.Script.pas', Myc.Ast.Script in '..\Src\AST\Myc.Ast.Script.pas',
Myc.Ast.Types in '..\Src\AST\Myc.Ast.Types.pas'; Myc.Ast.Types in '..\Src\AST\Myc.Ast.Types.pas',
Myc.Fmx.AstVisualizer in 'Myc.Fmx.AstVisualizer.pas';
{$R *.res} {$R *.res}
+1 -1
View File
@@ -138,7 +138,6 @@
<DCCReference Include="..\Src\AST\Myc.Ast.Evaluator.pas"/> <DCCReference Include="..\Src\AST\Myc.Ast.Evaluator.pas"/>
<DCCReference Include="..\Src\AST\Myc.Ast.Nodes.pas"/> <DCCReference Include="..\Src\AST\Myc.Ast.Nodes.pas"/>
<DCCReference Include="..\Src\AST\Myc.Ast.Scope.pas"/> <DCCReference Include="..\Src\AST\Myc.Ast.Scope.pas"/>
<DCCReference Include="Myc.Fmx.AstEditor.pas"/>
<DCCReference Include="Myc.Data.Value.pas"/> <DCCReference Include="Myc.Data.Value.pas"/>
<DCCReference Include="..\Src\AST\Myc.Ast.Debugger.pas"/> <DCCReference Include="..\Src\AST\Myc.Ast.Debugger.pas"/>
<DCCReference Include="..\Src\AST\Myc.Ast.Visitor.pas"/> <DCCReference Include="..\Src\AST\Myc.Ast.Visitor.pas"/>
@@ -152,6 +151,7 @@
<DCCReference Include="..\Src\Myc.Utils.pas"/> <DCCReference Include="..\Src\Myc.Utils.pas"/>
<DCCReference Include="..\Src\AST\Myc.Ast.Script.pas"/> <DCCReference Include="..\Src\AST\Myc.Ast.Script.pas"/>
<DCCReference Include="..\Src\AST\Myc.Ast.Types.pas"/> <DCCReference Include="..\Src\AST\Myc.Ast.Types.pas"/>
<DCCReference Include="Myc.Fmx.AstVisualizer.pas"/>
<BuildConfiguration Include="Base"> <BuildConfiguration Include="Base">
<Key>Base</Key> <Key>Base</Key>
</BuildConfiguration> </BuildConfiguration>
+13 -20
View File
@@ -89,96 +89,89 @@ object Form1: TForm1
Text = 'Clear' Text = 'Clear'
OnClick = ClearButtonClick OnClick = ClearButtonClick
end end
object FlowOnlyBox: TCheckBox
Position.X = 24.000000000000000000
Position.Y = 8.000000000000000000
TabOrder = 11
Text = 'Flow only'
OnChange = FlowOnlyBoxChange
end
object SeriesTestButton: TButton object SeriesTestButton: TButton
Position.X = 24.000000000000000000 Position.X = 24.000000000000000000
Position.Y = 258.000000000000000000 Position.Y = 258.000000000000000000
Size.Width = 80.000000000000000000 Size.Width = 80.000000000000000000
Size.Height = 22.000000000000000000 Size.Height = 22.000000000000000000
Size.PlatformDefault = False Size.PlatformDefault = False
TabOrder = 13 TabOrder = 12
Text = 'Series' Text = 'Series'
OnClick = SeriesTestButtonClick OnClick = SeriesTestButtonClick
end end
object OHLCButton: TButton object OHLCButton: TButton
Position.X = 24.000000000000000000 Position.X = 24.000000000000000000
Position.Y = 288.000000000000000000 Position.Y = 288.000000000000000000
TabOrder = 14 TabOrder = 13
Text = 'OHLC' Text = 'OHLC'
OnClick = OHLCButtonClick OnClick = OHLCButtonClick
end end
object DebugBox: TCheckBox object DebugBox: TCheckBox
Position.X = 24.000000000000000000 Position.X = 24.000000000000000000
Position.Y = 439.000000000000000000 Position.Y = 439.000000000000000000
TabOrder = 15 TabOrder = 14
Text = 'Debug' Text = 'Debug'
end end
object FromJSONButton: TButton object FromJSONButton: TButton
Position.X = 24.000000000000000000 Position.X = 24.000000000000000000
Position.Y = 569.000000000000000000 Position.Y = 569.000000000000000000
TabOrder = 16 TabOrder = 15
Text = 'From JSON' Text = 'From JSON'
OnClick = FromJSONButtonClick OnClick = FromJSONButtonClick
end end
object ToJSONButton: TButton object ToJSONButton: TButton
Position.X = 24.000000000000000000 Position.X = 24.000000000000000000
Position.Y = 599.000000000000000000 Position.Y = 599.000000000000000000
TabOrder = 17 TabOrder = 16
Text = 'To JSON' Text = 'To JSON'
OnClick = ToJSONButtonClick OnClick = ToJSONButtonClick
end end
object ExternalFuncButton: TButton object ExternalFuncButton: TButton
Position.X = 24.000000000000000000 Position.X = 24.000000000000000000
Position.Y = 318.000000000000000000 Position.Y = 318.000000000000000000
TabOrder = 18 TabOrder = 17
Text = 'External Func' Text = 'External Func'
OnClick = ExternalFuncButtonClick OnClick = ExternalFuncButtonClick
end end
object InnerLambdaButton: TButton object InnerLambdaButton: TButton
Position.X = 24.000000000000000000 Position.X = 24.000000000000000000
Position.Y = 348.000000000000000000 Position.Y = 348.000000000000000000
TabOrder = 19 TabOrder = 18
Text = 'Inner Lambda' Text = 'Inner Lambda'
OnClick = InnerLambdaButtonClick OnClick = InnerLambdaButtonClick
end end
object DumpButton: TButton object DumpButton: TButton
Position.X = 24.000000000000000000 Position.X = 24.000000000000000000
Position.Y = 509.000000000000000000 Position.Y = 509.000000000000000000
TabOrder = 20 TabOrder = 19
Text = 'Dump' Text = 'Dump'
OnClick = DumpButtonClick OnClick = DumpButtonClick
end end
object FailingUpvalueButton: TButton object FailingUpvalueButton: TButton
Position.X = 24.000000000000000000 Position.X = 24.000000000000000000
Position.Y = 378.000000000000000000 Position.Y = 378.000000000000000000
TabOrder = 22 TabOrder = 21
Text = 'Upvalue' Text = 'Upvalue'
OnClick = FailingUpvalueButtonClick OnClick = FailingUpvalueButtonClick
end end
object TailCallButten: TButton object TailCallButten: TButton
Position.X = 24.000000000000000000 Position.X = 24.000000000000000000
Position.Y = 406.000000000000000000 Position.Y = 406.000000000000000000
TabOrder = 23 TabOrder = 22
Text = 'Tail calls' Text = 'Tail calls'
OnClick = TailCallButtenClick OnClick = TailCallButtenClick
end end
object SaveUserLibButton: TButton object SaveUserLibButton: TButton
Position.X = 24.000000000000000000 Position.X = 24.000000000000000000
Position.Y = 629.000000000000000000 Position.Y = 629.000000000000000000
TabOrder = 24 TabOrder = 23
Text = 'Save Lib' Text = 'Save Lib'
OnClick = SaveUserLibButtonClick OnClick = SaveUserLibButtonClick
end end
object LoadUserLibButton: TButton object LoadUserLibButton: TButton
Position.X = 24.000000000000000000 Position.X = 24.000000000000000000
Position.Y = 659.000000000000000000 Position.Y = 659.000000000000000000
TabOrder = 25 TabOrder = 24
Text = 'LoadLib' Text = 'LoadLib'
OnClick = LoadUserLibButtonClick OnClick = LoadUserLibButtonClick
end end
@@ -193,7 +186,7 @@ object Form1: TForm1
Size.Width = 113.000000000000000000 Size.Width = 113.000000000000000000
Size.Height = 184.000000000000000000 Size.Height = 184.000000000000000000
Size.PlatformDefault = False Size.PlatformDefault = False
TabOrder = 26 TabOrder = 25
OnChange = RTLListViewChange OnChange = RTLListViewChange
end end
end end
+17 -14
View File
@@ -36,7 +36,7 @@ uses
FMX.Layouts, FMX.Layouts,
FMX.Objects, FMX.Objects,
Myc.Ast.Debugger, Myc.Ast.Debugger,
Myc.Fmx.AstEditor, Myc.Fmx.AstVisualizer,
Myc.Fmx.AstEditor.Node, Myc.Fmx.AstEditor.Node,
Myc.Fmx.AstEditor.Workspace, Myc.Fmx.AstEditor.Workspace,
FMX.DialogService, FMX.DialogService,
@@ -70,7 +70,6 @@ type
DoTrigger2Button: TButton; DoTrigger2Button: TButton;
Panel2: TPanel; Panel2: TPanel;
ClearButton: TButton; ClearButton: TButton;
FlowOnlyBox: TCheckBox;
SeriesTestButton: TButton; SeriesTestButton: TButton;
OHLCButton: TButton; OHLCButton: TButton;
DebugBox: TCheckBox; DebugBox: TCheckBox;
@@ -112,6 +111,7 @@ type
procedure LoadUserLibButtonClick(Sender: TObject); procedure LoadUserLibButtonClick(Sender: TObject);
procedure RTLListViewChange(Sender: TObject); procedure RTLListViewChange(Sender: TObject);
private private
FCurrUnboundAst: IAstNode;
FCurrAst: IAstNode; FCurrAst: IAstNode;
FCurrDesc: IScopeDescriptor; FCurrDesc: IScopeDescriptor;
FGScope: IExecutionScope; FGScope: IExecutionScope;
@@ -216,6 +216,7 @@ var
visitor: IEvaluatorVisitor; visitor: IEvaluatorVisitor;
begin begin
// The new, streamlined pipeline: The binder handles macro expansion internally. // The new, streamlined pipeline: The binder handles macro expansion internally.
FCurrUnboundAst := ANode;
// Step 1: Create a binder, passing the evaluator factory for compile-time evaluations. // Step 1: Create a binder, passing the evaluator factory for compile-time evaluations.
binder := TAstBinder.Create(AParentScope, CreateEvaluator); binder := TAstBinder.Create(AParentScope, CreateEvaluator);
@@ -1284,13 +1285,13 @@ begin
Memo1.Lines.Clear; Memo1.Lines.Clear;
try try
// Execute the entire script block when it changes try
var result := ExecuteAst(TAstScript.Parse(ScriptMemo.Lines.Text), FGScope); // Execute the entire script block when it changes
Memo1.Lines.Add(Format('Script executed. Final result: %s', [result.ToString])); var result := ExecuteAst(TAstScript.Parse(ScriptMemo.Lines.Text), FGScope);
Memo1.Lines.Add(Format('Script executed. Final result: %s', [result.ToString]));
// After execution, the FCurrAst is set by ExecuteAst, so we can visualize it finally
FWorkspace.DeleteChildren; ShowVizualization(14, 14);
ShowVizualization(14, 14); end;
except except
on E: Exception do on E: Exception do
Memo1.Lines.Add(E.Message); Memo1.Lines.Add(E.Message);
@@ -1307,13 +1308,15 @@ end;
procedure TForm1.ShowVizualization(X, Y: Single); procedure TForm1.ShowVizualization(X, Y: Single);
begin begin
FWorkspace.DeleteChildren;
if FCurrAst <> nil then if FCurrAst <> nil then
begin begin
var visu := TVisualizationMode.vmDetailed; FWorkspace.Build(FCurrAst, TPointF.Create(X, Y));
if FlowOnlyBox.IsChecked then end
visu := TVisualizationMode.vmControlFlow; else if FCurrUnboundAst <> nil then
begin
FWorkspace.BuildTree(FCurrAst, FCurrDesc, TPointF.Create(X, Y), visu); FWorkspace.Build(FCurrUnboundAst, TPointF.Create(X, Y));
end; end;
end; end;
+50 -84
View File
@@ -14,9 +14,10 @@ uses
FMX.Graphics; FMX.Graphics;
type type
// A movable panel with a custom-painted border and title. // A movable panel with a custom-painted border. Content (like title) is added externally.
TAuraNode = class(TStyledControl) TAuraNode = class(TStyledControl)
private private
FBackgroundColor: TAlphaColor;
// Flag to indicate if the control is currently being dragged. // Flag to indicate if the control is currently being dragged.
FIsDragging: Boolean; FIsDragging: Boolean;
// Stores the mouse coordinates at the beginning of the drag operation. // Stores the mouse coordinates at the beginning of the drag operation.
@@ -25,20 +26,13 @@ type
FBorderColor: TAlphaColor; FBorderColor: TAlphaColor;
FBorderWidth: Single; FBorderWidth: Single;
FBorderRadius: Single; FBorderRadius: Single;
// Properties for the title
FTitle: string;
FTitleFont: TFont;
FTitleFontColor: TAlphaColor;
// If true, the node is drawn without a border and with a transparent background. // If true, the node is drawn without a border and with a transparent background.
FFrameless: Boolean; FFrameless: Boolean;
procedure SetBackgroundColor(const Value: TAlphaColor);
procedure SetBorderColor(const Value: TAlphaColor); procedure SetBorderColor(const Value: TAlphaColor);
procedure SetBorderWidth(const Value: Single); procedure SetBorderWidth(const Value: Single);
procedure SetBorderRadius(const Value: Single); procedure SetBorderRadius(const Value: Single);
procedure SetTitle(const Value: string);
procedure SetTitleFont(const Value: TFont);
procedure SetTitleFontColor(const Value: TAlphaColor);
procedure TitleFontChanged(Sender: TObject);
procedure SetFrameless(const Value: Boolean); procedure SetFrameless(const Value: Boolean);
protected protected
procedure Paint; override; procedure Paint; override;
@@ -53,11 +47,7 @@ type
property BorderColor: TAlphaColor read FBorderColor write SetBorderColor; property BorderColor: TAlphaColor read FBorderColor write SetBorderColor;
property BorderWidth: Single read FBorderWidth write SetBorderWidth; property BorderWidth: Single read FBorderWidth write SetBorderWidth;
property BorderRadius: Single read FBorderRadius write SetBorderRadius; property BorderRadius: Single read FBorderRadius write SetBorderRadius;
property BackgroundColor: TAlphaColor read FBackgroundColor write SetBackgroundColor;
// Title properties
property Title: string read FTitle write SetTitle;
property TitleFont: TFont read FTitleFont write SetTitleFont;
property TitleFontColor: TAlphaColor read FTitleFontColor write SetTitleFontColor;
// Behavior properties // Behavior properties
property Frameless: Boolean read FFrameless write SetFrameless; property Frameless: Boolean read FFrameless write SetFrameless;
@@ -110,16 +100,8 @@ begin
// Default border settings // Default border settings
FBorderColor := TAlphaColors.Gray; FBorderColor := TAlphaColors.Gray;
FBorderWidth := 1; FBorderWidth := 1;
FBorderRadius := 9; // Sharp corners by default FBorderRadius := 9; // Rounded corners by default
FBackgroundColor := $080a0a0a;
// Default title settings
FTitle := 'Node';
FTitleFont := TFont.Create;
FTitleFont.Family := 'Segoe UI';
FTitleFont.Size := 11;
FTitleFont.Style := [TFontStyle.fsBold];
FTitleFont.OnChanged := TitleFontChanged;
FTitleFontColor := TAlphaColors.Black;
// Default state for frameless mode // Default state for frameless mode
FFrameless := False; FFrameless := False;
@@ -128,36 +110,51 @@ begin
Height := 45; Height := 45;
// The panel must be able to receive mouse events. // The panel must be able to receive mouse events.
// HitTest := True; HitTest := True; // Make sure HitTest is True to receive mouse events
// Clip children to the panel's bounds. // Clip children to the panel's bounds.
ClipChildren := True; ClipChildren := True;
end; end;
destructor TAuraNode.Destroy; destructor TAuraNode.Destroy;
begin begin
FTitleFont.Free;
inherited; inherited;
end; end;
procedure TAuraNode.Paint; procedure TAuraNode.Paint;
var var
rect, titleRect: TRectF; rect: TRectF;
effectiveBorderWidth: Single; effectiveBorderWidth: Single;
begin begin
inherited; // Allow styled painting to occur first (if any) inherited; // Allow styled painting to occur first (if any)
// Clear background before drawing custom border/fill
Canvas.Fill.Kind := TBrushKind.None; // Make sure default fill is cleared if needed
//Canvas.ClearRect(TRectF.Create(0,0, Width, Height)); // Optional: Explicit clear
if FFrameless then if FFrameless then
begin begin
Canvas.Fill.Kind := TBrushKind.Solid; Canvas.Fill.Kind := TBrushKind.Solid;
Canvas.Fill.Color := $20C0C0C0; // Transparent Silver Canvas.Fill.Color := FBackgroundColor;
Canvas.Stroke.Kind := TBrushKind.None; Canvas.Stroke.Kind := TBrushKind.None;
// In frameless mode, draw a transparent background and ignore the border.
Canvas.FillRect(TRectF.Create(0, 0, Width, Height), 0, 0, [], 1.0); Canvas.FillRect(TRectF.Create(0, 0, Width, Height), 0, 0, [], 1.0);
Canvas.Stroke.Kind := TBrushKind.Solid;
Canvas.Stroke.Color := FBorderColor;
Canvas.Stroke.Thickness := 1;
Canvas.Stroke.Dash := TStrokeDash.Dot;
Canvas.DrawRect(TRectF.Create(0, 0, Width, Height), 0, 0, [], 1.0);
effectiveBorderWidth := 0; effectiveBorderWidth := 0;
end end
else else
begin begin
// Draw background fill first
Canvas.Fill.Kind := TBrushKind.Solid;
Canvas.Fill.Color := FBackgroundColor;
rect := TRectF.Create(0, 0, Width, Height);
// Inflate inwards slightly if border exists to avoid overlap issues
if (FBorderWidth > 0) then
rect.Inflate(-FBorderWidth / 2, -FBorderWidth / 2);
Canvas.FillRect(rect, FBorderRadius, FBorderRadius, AllCorners, 1.0, TCornerType.Round);
// Custom painting for the border // Custom painting for the border
if (FBorderWidth > 0) and (FBorderColor <> TAlphaColors.Null) then if (FBorderWidth > 0) and (FBorderColor <> TAlphaColors.Null) then
begin begin
@@ -168,31 +165,15 @@ begin
Canvas.Stroke.Kind := TBrushKind.Solid; Canvas.Stroke.Kind := TBrushKind.Solid;
Canvas.Stroke.Color := FBorderColor; Canvas.Stroke.Color := FBorderColor;
Canvas.Stroke.Thickness := FBorderWidth; Canvas.Stroke.Thickness := FBorderWidth;
Canvas.Stroke.Dash := TStrokeDash.Solid;
Canvas.DrawRect(rect, FBorderRadius, FBorderRadius, AllCorners, 1.0, TCornerType.Round);
if FFrameless then effectiveBorderWidth := FBorderWidth;
begin end
Canvas.Fill.Kind := TBrushKind.Solid; else
Canvas.Fill.Color := $20C0C0C0; // Transparent Silver effectiveBorderWidth := 0;
Canvas.FillRect(rect, FBorderRadius, FBorderRadius, AllCorners, 1.0, TCornerType.Round);
end
else
Canvas.DrawRect(rect, FBorderRadius, FBorderRadius, AllCorners, 1.0, TCornerType.Round);
end;
effectiveBorderWidth := FBorderWidth;
end;
// Draw the title
if not FTitle.IsEmpty then
begin
// Define the rectangle for the title at the top of the control
titleRect := TRectF.Create(0, effectiveBorderWidth, Width, effectiveBorderWidth + FTitleFont.Size * 1.8);
Canvas.Font.Assign(FTitleFont);
Canvas.Fill.Color := FTitleFontColor;
// Draw the text centered horizontally and vertically within the title rectangle
Canvas.FillText(titleRect, FTitle, False, 1.0, [], TTextAlign.Center, TTextAlign.Center);
end; end;
// Title drawing removed, handled by external labels now.
end; end;
procedure TAuraNode.SetBorderColor(const Value: TAlphaColor); procedure TAuraNode.SetBorderColor(const Value: TAlphaColor);
@@ -231,45 +212,22 @@ begin
end; end;
end; end;
procedure TAuraNode.SetTitle(const Value: string);
begin
if FTitle <> Value then
begin
FTitle := Value;
Repaint;
end;
end;
procedure TAuraNode.SetTitleFont(const Value: TFont);
begin
FTitleFont.Assign(Value);
end;
procedure TAuraNode.SetTitleFontColor(const Value: TAlphaColor);
begin
if FTitleFontColor <> Value then
begin
FTitleFontColor := Value;
Repaint;
end;
end;
procedure TAuraNode.TitleFontChanged(Sender: TObject);
begin
Repaint;
end;
procedure TAuraNode.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Single); procedure TAuraNode.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Single);
begin begin
inherited; inherited;
if Button = TMouseButton.mbLeft then if Button = TMouseButton.mbLeft then
begin begin
if ObjectAtPoint(LocalToScreen(TPointF.Create(X, Y))) = Self as IControl then // Only start dragging if the click is on the node itself, not its children
var LControl := ObjectAtPoint(LocalToScreen(TPointF.Create(X, Y)));
if Assigned(LControl) and (LControl.GetObject = Self) then
begin begin
FIsDragging := True; FIsDragging := True;
FDownPos := TPointF.Create(X, Y); FDownPos := TPointF.Create(X, Y);
Capture; Capture;
end; BringToFront; // Bring node to front when dragging starts
end
else
FIsDragging := False; // Ensure dragging stops if click is on a child
end; end;
end; end;
@@ -286,7 +244,7 @@ begin
Position.Y := Position.Y + deltaY; Position.Y := Position.Y + deltaY;
if ParentControl <> nil then if ParentControl <> nil then
ParentControl.Repaint; ParentControl.Repaint; // Repaint the workspace to update connections
end; end;
end; end;
@@ -297,7 +255,15 @@ begin
begin begin
ReleaseCapture; ReleaseCapture;
FIsDragging := False; FIsDragging := False;
if ParentControl <> nil then // Repaint one last time after drag ends
ParentControl.Repaint;
end; end;
end; end;
procedure TAuraNode.SetBackgroundColor(const Value: TAlphaColor);
begin
FBackgroundColor := Value;
Repaint;
end;
end. end.
+8 -26
View File
@@ -18,6 +18,10 @@ uses
Myc.Ast.Scope, Myc.Ast.Scope,
Myc.Ast.Binding; Myc.Ast.Binding;
const
cDataPinColor = TAlphaColors.Dodgerblue;
cExecPinColor = TAlphaColors.Lightgreen;
type type
TPinConnection = record TPinConnection = record
OutputPin: TControl; OutputPin: TControl;
@@ -25,9 +29,6 @@ type
constructor Create(AOutputPin, AInputPin: TControl); constructor Create(AOutputPin, AInputPin: TControl);
end; end;
// Enum to select the visualization style.
TVisualizationMode = (vmDetailed, vmControlFlow);
TAuraWorkspace = class(TStyledControl) TAuraWorkspace = class(TStyledControl)
private private
FConnections: TArray<TPinConnection>; FConnections: TArray<TPinConnection>;
@@ -45,12 +46,7 @@ type
procedure DblClick; override; procedure DblClick; override;
public public
constructor Create(AOwner: TComponent); override; constructor Create(AOwner: TComponent); override;
procedure BuildTree( procedure Build(const RootNode: IAstNode; const Position: TPointF);
const RootNode: IAstNode;
const RootDescriptor: IScopeDescriptor;
const Position: TPointF;
AMode: TVisualizationMode
);
function GetChildrenMatrix(var Matrix: TMatrix; var Simple: Boolean): Boolean; override; function GetChildrenMatrix(var Matrix: TMatrix; var Simple: Boolean): Boolean; override;
function Zoom(Factor: Single): Boolean; function Zoom(Factor: Single): Boolean;
@@ -95,7 +91,7 @@ implementation
uses uses
System.Math, System.Math,
FMX.Platform, FMX.Platform,
Myc.Fmx.AstEditor; Myc.Fmx.AstVisualizer;
{ TPinConnection } { TPinConnection }
@@ -113,23 +109,9 @@ begin
FZoom := 1.0; FZoom := 1.0;
end; end;
procedure TAuraWorkspace.BuildTree( procedure TAuraWorkspace.Build(const RootNode: IAstNode; const Position: TPointF);
const RootNode: IAstNode;
const RootDescriptor: IScopeDescriptor;
const Position: TPointF;
AMode: TVisualizationMode
);
var
connections: TList<TPinConnection>;
begin begin
connections := TList<TPinConnection>.Create; RootNode.Accept(TAstVisualizer.CreateVisitor(Self, Position));
try
// Create the scope descriptor from the execution scope provided by the binder.
RootNode.Accept(TAstToAuraNodeVisitor.Create(Self, Self, Position, connections, nil, AMode, nil, nil, RootDescriptor));
FConnections := FConnections + connections.ToArray;
finally
connections.Free;
end;
end; end;
procedure TAuraWorkspace.DoDeleteChildren; procedure TAuraWorkspace.DoDeleteChildren;
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff