diff --git a/ASTPlayground/ASTPlayground.delphilsp.json b/ASTPlayground/ASTPlayground.delphilsp.json index c4a2d82..37b65e5 100644 --- a/ASTPlayground/ASTPlayground.delphilsp.json +++ b/ASTPlayground/ASTPlayground.delphilsp.json @@ -1 +1 @@ -{ "settings": { "project": "file:///T%3A/Myc/ASTPlayground/ASTPlayground.dpr", "dllname": "dcc64370.dll", "dccOptions": "-$O- -$W+ --inline:off -$R+ -$Q+ --no-config -Q -TX.exe -AGenerics.Collections=System.Generics.Collections;Generics.Defaults=System.Generics.Defaults;WinTypes=Winapi.Windows;WinProcs=Winapi.Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE -DDEBUG;;FRAMEWORK_FMX -E.\\Win64\\Debug -I\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\debug\\DE\";\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\debug\";\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\release\\DE\";T:\\Myc\\Src\\Data;T:\\Myc\\Src\\AST;T:\\Myc\\Src;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\release\";C:\\Users\\Brummel\\Documents\\Embarcadero\\Studio\\37.0\\Imports\\Win64;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\Imports\";C:\\Users\\Public\\Documents\\Embarcadero\\Studio\\37.0\\Dcp\\Win64;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\include\";S:\\sc_famos_src\\svn_vcl\\Virtual-TreeView\\Source;S:\\sc_famos_src\\svn_vcl\\cpxedits;S:\\sc_famos_src\\svn_vcl\\dzChart;S:\\sc_famos_src\\svn_vcl\\eaeditor;S:\\sc_famos_src\\svn_vcl\\FamosEvents;S:\\sc_famos_src\\svn_vcl\\HTML_Viewer\\source;S:\\sc_famos_src\\svn_vcl\\Myc_ChartEdit;S:\\sc_famos_src\\svn_vcl\\Myc_HemiDrag;S:\\sc_famos_src\\svn_vcl\\Myc_SplitControl;S:\\sc_famos_src\\svn_vcl\\plotter;S:\\sc_famos_src\\svn_vcl\\SimpleIPC;S:\\sc_famos_src\\svn_vcl\\SynEdit-master\\Source;S:\\sc_famos_src\\svn_vcl\\ValEdits;S:\\sc_famos_src\\svn_vcl\\ZipMaster;S:\\sc_famos_src\\svn_common\\Myc_VecMath;\"C:\\Program Files (x86)\\DevExpress VCL\\Library\\RS28\\Win64\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressCore Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressCommon Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressGDI+ Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressLibrary\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\XP Theme Manager\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressLayout Control\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressPageControl\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressEditors Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressDocking Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressBars\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressOfficeCore Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressMemData\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressDataController\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressNavBar\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressSkins Library\\Sources\";S:\\3rdParty\\FastMM5;C:\\Users\\Brummel\\AppData\\Local\\Programs\\TestInsight\\Source;T:\\Myc\\Src;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\source\\DUnitX\" -LEC:\\Users\\Public\\Documents\\Embarcadero\\Studio\\37.0\\Bpl\\Win64 -LNC:\\Users\\Public\\Documents\\Embarcadero\\Studio\\37.0\\Dcp\\Win64 -NU.\\Win64\\Debug -NSWinapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;System;Xml;Data;Datasnap;Web;Soap; -OT:\\Myc\\Src\\Data;T:\\Myc\\Src\\AST;T:\\Myc\\Src;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\release\";C:\\Users\\Brummel\\Documents\\Embarcadero\\Studio\\37.0\\Imports\\Win64;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\Imports\";C:\\Users\\Public\\Documents\\Embarcadero\\Studio\\37.0\\Dcp\\Win64;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\include\";S:\\sc_famos_src\\svn_vcl\\Virtual-TreeView\\Source;S:\\sc_famos_src\\svn_vcl\\cpxedits;S:\\sc_famos_src\\svn_vcl\\dzChart;S:\\sc_famos_src\\svn_vcl\\eaeditor;S:\\sc_famos_src\\svn_vcl\\FamosEvents;S:\\sc_famos_src\\svn_vcl\\HTML_Viewer\\source;S:\\sc_famos_src\\svn_vcl\\Myc_ChartEdit;S:\\sc_famos_src\\svn_vcl\\Myc_HemiDrag;S:\\sc_famos_src\\svn_vcl\\Myc_SplitControl;S:\\sc_famos_src\\svn_vcl\\plotter;S:\\sc_famos_src\\svn_vcl\\SimpleIPC;S:\\sc_famos_src\\svn_vcl\\SynEdit-master\\Source;S:\\sc_famos_src\\svn_vcl\\ValEdits;S:\\sc_famos_src\\svn_vcl\\ZipMaster;S:\\sc_famos_src\\svn_common\\Myc_VecMath;\"C:\\Program Files (x86)\\DevExpress VCL\\Library\\RS28\\Win64\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressCore Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressCommon Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressGDI+ Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressLibrary\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\XP Theme Manager\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressLayout Control\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressPageControl\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressEditors Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressDocking Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressBars\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressOfficeCore Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressMemData\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressDataController\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressNavBar\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressSkins Library\\Sources\";S:\\3rdParty\\FastMM5;C:\\Users\\Brummel\\AppData\\Local\\Programs\\TestInsight\\Source;T:\\Myc\\Src;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\source\\DUnitX\" -R\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\release\\DE\";T:\\Myc\\Src\\Data;T:\\Myc\\Src\\AST;T:\\Myc\\Src;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\release\";C:\\Users\\Brummel\\Documents\\Embarcadero\\Studio\\37.0\\Imports\\Win64;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\Imports\";C:\\Users\\Public\\Documents\\Embarcadero\\Studio\\37.0\\Dcp\\Win64;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\include\";S:\\sc_famos_src\\svn_vcl\\Virtual-TreeView\\Source;S:\\sc_famos_src\\svn_vcl\\cpxedits;S:\\sc_famos_src\\svn_vcl\\dzChart;S:\\sc_famos_src\\svn_vcl\\eaeditor;S:\\sc_famos_src\\svn_vcl\\FamosEvents;S:\\sc_famos_src\\svn_vcl\\HTML_Viewer\\source;S:\\sc_famos_src\\svn_vcl\\Myc_ChartEdit;S:\\sc_famos_src\\svn_vcl\\Myc_HemiDrag;S:\\sc_famos_src\\svn_vcl\\Myc_SplitControl;S:\\sc_famos_src\\svn_vcl\\plotter;S:\\sc_famos_src\\svn_vcl\\SimpleIPC;S:\\sc_famos_src\\svn_vcl\\SynEdit-master\\Source;S:\\sc_famos_src\\svn_vcl\\ValEdits;S:\\sc_famos_src\\svn_vcl\\ZipMaster;S:\\sc_famos_src\\svn_common\\Myc_VecMath;\"C:\\Program Files (x86)\\DevExpress VCL\\Library\\RS28\\Win64\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressCore Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressCommon Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressGDI+ Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressLibrary\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\XP Theme Manager\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressLayout Control\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressPageControl\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressEditors Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressDocking Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressBars\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressOfficeCore Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressMemData\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressDataController\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressNavBar\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressSkins Library\\Sources\";S:\\3rdParty\\FastMM5;C:\\Users\\Brummel\\AppData\\Local\\Programs\\TestInsight\\Source;T:\\Myc\\Src;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\source\\DUnitX\" -U\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\debug\\DE\";\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\debug\";\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\release\\DE\";T:\\Myc\\Src\\Data;T:\\Myc\\Src\\AST;T:\\Myc\\Src;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\release\";C:\\Users\\Brummel\\Documents\\Embarcadero\\Studio\\37.0\\Imports\\Win64;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\Imports\";C:\\Users\\Public\\Documents\\Embarcadero\\Studio\\37.0\\Dcp\\Win64;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\include\";S:\\sc_famos_src\\svn_vcl\\Virtual-TreeView\\Source;S:\\sc_famos_src\\svn_vcl\\cpxedits;S:\\sc_famos_src\\svn_vcl\\dzChart;S:\\sc_famos_src\\svn_vcl\\eaeditor;S:\\sc_famos_src\\svn_vcl\\FamosEvents;S:\\sc_famos_src\\svn_vcl\\HTML_Viewer\\source;S:\\sc_famos_src\\svn_vcl\\Myc_ChartEdit;S:\\sc_famos_src\\svn_vcl\\Myc_HemiDrag;S:\\sc_famos_src\\svn_vcl\\Myc_SplitControl;S:\\sc_famos_src\\svn_vcl\\plotter;S:\\sc_famos_src\\svn_vcl\\SimpleIPC;S:\\sc_famos_src\\svn_vcl\\SynEdit-master\\Source;S:\\sc_famos_src\\svn_vcl\\ValEdits;S:\\sc_famos_src\\svn_vcl\\ZipMaster;S:\\sc_famos_src\\svn_common\\Myc_VecMath;\"C:\\Program Files (x86)\\DevExpress VCL\\Library\\RS28\\Win64\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressCore Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressCommon Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressGDI+ Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressLibrary\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\XP Theme Manager\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressLayout Control\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressPageControl\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressEditors Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressDocking Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressBars\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressOfficeCore Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressMemData\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressDataController\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressNavBar\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressSkins Library\\Sources\";S:\\3rdParty\\FastMM5;C:\\Users\\Brummel\\AppData\\Local\\Programs\\TestInsight\\Source;T:\\Myc\\Src;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\source\\DUnitX\" -V -VN -VR -NBC:\\Users\\Public\\Documents\\Embarcadero\\Studio\\37.0\\Dcp\\Win64 -NHC:\\Users\\Public\\Documents\\Embarcadero\\Studio\\37.0\\hpp\\Win64 -NO.\\Win64\\Debug -LU" , "projectFiles":[ { "name": "MainForm", "file": "file:///T%3A/Myc/ASTPlayground/MainForm.pas" }, { "name": "Myc.Ast.Nodes", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Nodes.pas" }, { "name": "Myc.Ast.Scope", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Scope.pas" }, { "name": "Myc.Data.Value", "file": "file:///T%3A/Myc/ASTPlayground/Myc.Data.Value.pas" }, { "name": "Myc.Ast.Visitor", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Visitor.pas" }, { "name": "Myc.Ast.RTL", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.RTL.pas" }, { "name": "Myc.Ast.Dumper", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Dumper.pas" }, { "name": "Myc.Ast.RTL.Core", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.RTL.Core.pas" }, { "name": "Myc.Utils", "file": "file:///T%3A/Myc/Src/Myc.Utils.pas" }, { "name": "Myc.Ast.Script", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Script.pas" }, { "name": "Myc.Ast.Types", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Types.pas" }, { "name": "Myc.Data.Keyword", "file": "file:///T%3A/Myc/Src/Data/Myc.Data.Keyword.pas" }, { "name": "Myc.Ast.Compiler.TCO", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Compiler.TCO.pas" }, { "name": "Myc.Ast.Compiler.Binder", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Compiler.Binder.pas" }, { "name": "Myc.Ast.Compiler.Lowering", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Compiler.Lowering.pas" }, { "name": "Myc.Ast.Compiler.TypeChecker", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Compiler.TypeChecker.pas" }, { "name": "Myc.Ast.Compiler.Macros", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Compiler.Macros.pas" }, { "name": "Myc.Ast.Compiler.Specializer", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Compiler.Specializer.pas" }, { "name": "Myc.Ast.Environment", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Environment.pas" }, { "name": "Myc.Ast.Debugger", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Debugger.pas" }, { "name": "Myc.Ast.Analysis.Purity", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Analysis.Purity.pas" }, { "name": "Myc.Ast.Identities", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Identities.pas" }, { "name": "Myc.Fmx.AstEditor.Core", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Core.pas" }, { "name": "Myc.Fmx.AstEditor.Handlers", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Handlers.pas" }, { "name": "Myc.Fmx.AstEditor.Visualizer", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Visualizer.pas" }, { "name": "Myc.Fmx.AstEditor.Workspace", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Workspace.pas" }, { "name": "Myc.Fmx.AstEditor.Controller", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Controller.pas" } ] , "includeDCUsInUsesCompletion": true, "enableKeyWordCompletion": true, "browsingPaths": [ "file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/OCX/Servers","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/SOURCE/VCL","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/rtl/common","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/SOURCE/RTL/SYS","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/rtl/win","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/rtl/win/winrt","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/ToolsAPI","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/SOURCE/IBX","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/Internet","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/SOURCE/PROPERTY%20EDITORS","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/soap","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/SOURCE/XML","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/Indy10/Core","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/Indy10/System","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/Indy10/Protocols","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/fmx","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/databinding/components","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/databinding/engine","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/databinding/graph","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/ado","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/cloud","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/datasnap","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/dbx","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/dsnap","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/vclctrls","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/datasnap/connectors","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/datasnap/proxygen","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DataExplorer","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/Contrib/DUnitWizard/Source/Common","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/Contrib/DUnitWizard/Source/Common/dunit","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/Contrib/DUnitWizard/Source/DelphiExperts/Common","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/Contrib/DUnitWizard/Source/DelphiExperts/DUnitProject","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/Contrib/DUnitWizard/Source/DelphiExperts/DUnitProject/dunit","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/src","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/tests","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/Experts","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/indy/abstraction","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/indy/implementation","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/indyimpl","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/Property%20Editors/Indy10","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/soap/wsdlimporter","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/Visualizers","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/Contrib/XMLReporting","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/Contrib/XPGen","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/rest","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/firedac","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/tethering","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnitX","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/ems","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/rtl/net","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/FlatBox2D","file:///C%3A/Users/Public/Documents/Embarcadero/Studio/37.0/Dcp/%25PLATFORM%25","file:///%25TP%25/runtime/vcl","file:///S%3A/sc_famos_src/svn_vcl/cpxedits","file:///S%3A/sc_famos_src/svn_vcl/dzChart","file:///S%3A/sc_famos_src/svn_vcl/eaeditor","file:///S%3A/sc_famos_src/svn_vcl/FamosEvents","file:///S%3A/sc_famos_src/svn_vcl/HTML_Viewer/source","file:///S%3A/sc_famos_src/svn_vcl/Myc_ChartEdit","file:///S%3A/sc_famos_src/svn_vcl/Myc_HemiDrag","file:///S%3A/sc_famos_src/svn_vcl/Myc_SplitControl","file:///S%3A/sc_famos_src/svn_vcl/NiceChart","file:///S%3A/sc_famos_src/svn_vcl/plotter","file:///S%3A/sc_famos_src/svn_vcl/SimpleIPC","file:///S%3A/sc_famos_src/svn_vcl/SynEdit-master/Source","file:///S%3A/sc_famos_src/svn_vcl/ValEdits","file:///S%3A/sc_famos_src/svn_vcl/ZipMaster","file:///S%3A/sc_famos_src/svn_vcl/ZipMaster/zlib","file:///S%3A/sc_famos_src/svn_vcl/ZipMaster/zlib/win32","file:///S%3A/sc_famos_src/svn_vcl/Virtual-TreeView/Source","file:///S%3A/sc_famos_src/svn_common/caHelpSys","file:///S%3A/sc_famos_src/svn_common/Misc","file:///S%3A/sc_famos_src/svn_common/Myc_VecMath","file:///S%3A/sc_famos_src/svn_common/PascalScript/source","file:///S%3A/sc_famos_src/svn_common/TreeBase","file:///S%3A/sc_famos_src/svn_common/TreeBase/Medien","file:///S%3A/3rdParty/spring4d/Source","file:///S%3A/3rdParty/spring4d/Source/Base","file:///S%3A/3rdParty/spring4d/Source/Base/Collections","file:///S%3A/3rdParty/spring4d/Source/Base/Logging","file:///S%3A/3rdParty/spring4d/Source/Base/Patches","file:///S%3A/3rdParty/spring4d/Source/Core/Container","file:///S%3A/3rdParty/spring4d/Source/Core/Interception","file:///S%3A/3rdParty/spring4d/Source/Core/Logging","file:///S%3A/3rdParty/spring4d/Source/Core/Mocking","file:///S%3A/3rdParty/spring4d/Source/Core/Services","file:///S%3A/3rdParty/spring4d/Source/Extensions/Cryptography","file:///S%3A/3rdParty/spring4d/Source/Extensions/Utils","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressCore%20Library/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressCommon%20Library/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressGDI%2B%20Library/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressLibrary/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/XP%20Theme%20Manager/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressLayout%20Control/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressPageControl/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressEditors%20Library/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressDocking%20Library/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressBars/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressOfficeCore%20Library/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressMemData/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressDataController/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressNavBar/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressSkins%20Library/Sources","file:///T%3A/Myc/Src","file:///T%3A/Myc/Src/Data","file:///T%3A/Myc/Src/AST" ] , "CommonAppData": "file:///C%3A/Users/Brummel/AppData/Roaming/Embarcadero/BDS/37.0/" , "Templates": "file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/ObjRepos/" } } \ No newline at end of file +{ "settings": { "project": "file:///T%3A/Myc/ASTPlayground/ASTPlayground.dpr", "dllname": "dcc64370.dll", "dccOptions": "-$O- -$W+ --inline:off -$R+ -$Q+ --no-config -Q -TX.exe -AGenerics.Collections=System.Generics.Collections;Generics.Defaults=System.Generics.Defaults;WinTypes=Winapi.Windows;WinProcs=Winapi.Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE -DDEBUG;;FRAMEWORK_FMX -E.\\Win64\\Debug -I\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\debug\\DE\";\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\debug\";\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\release\\DE\";T:\\Myc\\Src\\Data;T:\\Myc\\Src\\AST;T:\\Myc\\Src;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\release\";C:\\Users\\Brummel\\Documents\\Embarcadero\\Studio\\37.0\\Imports\\Win64;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\Imports\";C:\\Users\\Public\\Documents\\Embarcadero\\Studio\\37.0\\Dcp\\Win64;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\include\";S:\\sc_famos_src\\svn_vcl\\Virtual-TreeView\\Source;S:\\sc_famos_src\\svn_vcl\\cpxedits;S:\\sc_famos_src\\svn_vcl\\dzChart;S:\\sc_famos_src\\svn_vcl\\eaeditor;S:\\sc_famos_src\\svn_vcl\\FamosEvents;S:\\sc_famos_src\\svn_vcl\\HTML_Viewer\\source;S:\\sc_famos_src\\svn_vcl\\Myc_ChartEdit;S:\\sc_famos_src\\svn_vcl\\Myc_HemiDrag;S:\\sc_famos_src\\svn_vcl\\Myc_SplitControl;S:\\sc_famos_src\\svn_vcl\\plotter;S:\\sc_famos_src\\svn_vcl\\SimpleIPC;S:\\sc_famos_src\\svn_vcl\\SynEdit-master\\Source;S:\\sc_famos_src\\svn_vcl\\ValEdits;S:\\sc_famos_src\\svn_vcl\\ZipMaster;S:\\sc_famos_src\\svn_common\\Myc_VecMath;\"C:\\Program Files (x86)\\DevExpress VCL\\Library\\RS28\\Win64\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressCore Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressCommon Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressGDI+ Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressLibrary\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\XP Theme Manager\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressLayout Control\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressPageControl\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressEditors Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressDocking Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressBars\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressOfficeCore Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressMemData\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressDataController\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressNavBar\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressSkins Library\\Sources\";S:\\3rdParty\\FastMM5;C:\\Users\\Brummel\\AppData\\Local\\Programs\\TestInsight\\Source;T:\\Myc\\Src;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\source\\DUnitX\" -LEC:\\Users\\Public\\Documents\\Embarcadero\\Studio\\37.0\\Bpl\\Win64 -LNC:\\Users\\Public\\Documents\\Embarcadero\\Studio\\37.0\\Dcp\\Win64 -NU.\\Win64\\Debug -NSWinapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;System;Xml;Data;Datasnap;Web;Soap; -OT:\\Myc\\Src\\Data;T:\\Myc\\Src\\AST;T:\\Myc\\Src;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\release\";C:\\Users\\Brummel\\Documents\\Embarcadero\\Studio\\37.0\\Imports\\Win64;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\Imports\";C:\\Users\\Public\\Documents\\Embarcadero\\Studio\\37.0\\Dcp\\Win64;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\include\";S:\\sc_famos_src\\svn_vcl\\Virtual-TreeView\\Source;S:\\sc_famos_src\\svn_vcl\\cpxedits;S:\\sc_famos_src\\svn_vcl\\dzChart;S:\\sc_famos_src\\svn_vcl\\eaeditor;S:\\sc_famos_src\\svn_vcl\\FamosEvents;S:\\sc_famos_src\\svn_vcl\\HTML_Viewer\\source;S:\\sc_famos_src\\svn_vcl\\Myc_ChartEdit;S:\\sc_famos_src\\svn_vcl\\Myc_HemiDrag;S:\\sc_famos_src\\svn_vcl\\Myc_SplitControl;S:\\sc_famos_src\\svn_vcl\\plotter;S:\\sc_famos_src\\svn_vcl\\SimpleIPC;S:\\sc_famos_src\\svn_vcl\\SynEdit-master\\Source;S:\\sc_famos_src\\svn_vcl\\ValEdits;S:\\sc_famos_src\\svn_vcl\\ZipMaster;S:\\sc_famos_src\\svn_common\\Myc_VecMath;\"C:\\Program Files (x86)\\DevExpress VCL\\Library\\RS28\\Win64\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressCore Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressCommon Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressGDI+ Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressLibrary\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\XP Theme Manager\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressLayout Control\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressPageControl\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressEditors Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressDocking Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressBars\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressOfficeCore Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressMemData\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressDataController\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressNavBar\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressSkins Library\\Sources\";S:\\3rdParty\\FastMM5;C:\\Users\\Brummel\\AppData\\Local\\Programs\\TestInsight\\Source;T:\\Myc\\Src;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\source\\DUnitX\" -R\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\release\\DE\";T:\\Myc\\Src\\Data;T:\\Myc\\Src\\AST;T:\\Myc\\Src;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\release\";C:\\Users\\Brummel\\Documents\\Embarcadero\\Studio\\37.0\\Imports\\Win64;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\Imports\";C:\\Users\\Public\\Documents\\Embarcadero\\Studio\\37.0\\Dcp\\Win64;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\include\";S:\\sc_famos_src\\svn_vcl\\Virtual-TreeView\\Source;S:\\sc_famos_src\\svn_vcl\\cpxedits;S:\\sc_famos_src\\svn_vcl\\dzChart;S:\\sc_famos_src\\svn_vcl\\eaeditor;S:\\sc_famos_src\\svn_vcl\\FamosEvents;S:\\sc_famos_src\\svn_vcl\\HTML_Viewer\\source;S:\\sc_famos_src\\svn_vcl\\Myc_ChartEdit;S:\\sc_famos_src\\svn_vcl\\Myc_HemiDrag;S:\\sc_famos_src\\svn_vcl\\Myc_SplitControl;S:\\sc_famos_src\\svn_vcl\\plotter;S:\\sc_famos_src\\svn_vcl\\SimpleIPC;S:\\sc_famos_src\\svn_vcl\\SynEdit-master\\Source;S:\\sc_famos_src\\svn_vcl\\ValEdits;S:\\sc_famos_src\\svn_vcl\\ZipMaster;S:\\sc_famos_src\\svn_common\\Myc_VecMath;\"C:\\Program Files (x86)\\DevExpress VCL\\Library\\RS28\\Win64\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressCore Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressCommon Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressGDI+ Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressLibrary\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\XP Theme Manager\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressLayout Control\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressPageControl\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressEditors Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressDocking Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressBars\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressOfficeCore Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressMemData\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressDataController\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressNavBar\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressSkins Library\\Sources\";S:\\3rdParty\\FastMM5;C:\\Users\\Brummel\\AppData\\Local\\Programs\\TestInsight\\Source;T:\\Myc\\Src;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\source\\DUnitX\" -U\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\debug\\DE\";\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\debug\";\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\release\\DE\";T:\\Myc\\Src\\Data;T:\\Myc\\Src\\AST;T:\\Myc\\Src;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\lib\\Win64\\release\";C:\\Users\\Brummel\\Documents\\Embarcadero\\Studio\\37.0\\Imports\\Win64;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\Imports\";C:\\Users\\Public\\Documents\\Embarcadero\\Studio\\37.0\\Dcp\\Win64;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\include\";S:\\sc_famos_src\\svn_vcl\\Virtual-TreeView\\Source;S:\\sc_famos_src\\svn_vcl\\cpxedits;S:\\sc_famos_src\\svn_vcl\\dzChart;S:\\sc_famos_src\\svn_vcl\\eaeditor;S:\\sc_famos_src\\svn_vcl\\FamosEvents;S:\\sc_famos_src\\svn_vcl\\HTML_Viewer\\source;S:\\sc_famos_src\\svn_vcl\\Myc_ChartEdit;S:\\sc_famos_src\\svn_vcl\\Myc_HemiDrag;S:\\sc_famos_src\\svn_vcl\\Myc_SplitControl;S:\\sc_famos_src\\svn_vcl\\plotter;S:\\sc_famos_src\\svn_vcl\\SimpleIPC;S:\\sc_famos_src\\svn_vcl\\SynEdit-master\\Source;S:\\sc_famos_src\\svn_vcl\\ValEdits;S:\\sc_famos_src\\svn_vcl\\ZipMaster;S:\\sc_famos_src\\svn_common\\Myc_VecMath;\"C:\\Program Files (x86)\\DevExpress VCL\\Library\\RS28\\Win64\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressCore Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressCommon Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressGDI+ Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressLibrary\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\XP Theme Manager\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressLayout Control\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressPageControl\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressEditors Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressDocking Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressBars\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressOfficeCore Library\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressMemData\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressDataController\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressNavBar\\Sources\";\"C:\\Program Files (x86)\\DevExpress VCL\\ExpressSkins Library\\Sources\";S:\\3rdParty\\FastMM5;C:\\Users\\Brummel\\AppData\\Local\\Programs\\TestInsight\\Source;T:\\Myc\\Src;\"c:\\program files (x86)\\embarcadero\\studio\\37.0\\source\\DUnitX\" -V -VN -VR -NBC:\\Users\\Public\\Documents\\Embarcadero\\Studio\\37.0\\Dcp\\Win64 -NHC:\\Users\\Public\\Documents\\Embarcadero\\Studio\\37.0\\hpp\\Win64 -NO.\\Win64\\Debug -LU" , "projectFiles":[ { "name": "MainForm", "file": "file:///T%3A/Myc/ASTPlayground/MainForm.pas" }, { "name": "Myc.Ast.Nodes", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Nodes.pas" }, { "name": "Myc.Ast.Scope", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Scope.pas" }, { "name": "Myc.Data.Value", "file": "file:///T%3A/Myc/ASTPlayground/Myc.Data.Value.pas" }, { "name": "Myc.Ast.Visitor", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Visitor.pas" }, { "name": "Myc.Ast.RTL", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.RTL.pas" }, { "name": "Myc.Ast.Dumper", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Dumper.pas" }, { "name": "Myc.Ast.RTL.Core", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.RTL.Core.pas" }, { "name": "Myc.Utils", "file": "file:///T%3A/Myc/Src/Myc.Utils.pas" }, { "name": "Myc.Ast.Script", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Script.pas" }, { "name": "Myc.Ast.Types", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Types.pas" }, { "name": "Myc.Data.Keyword", "file": "file:///T%3A/Myc/Src/Data/Myc.Data.Keyword.pas" }, { "name": "Myc.Ast.Compiler.TCO", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Compiler.TCO.pas" }, { "name": "Myc.Ast.Compiler.Binder", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Compiler.Binder.pas" }, { "name": "Myc.Ast.Compiler.Lowering", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Compiler.Lowering.pas" }, { "name": "Myc.Ast.Compiler.TypeChecker", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Compiler.TypeChecker.pas" }, { "name": "Myc.Ast.Compiler.Macros", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Compiler.Macros.pas" }, { "name": "Myc.Ast.Compiler.Specializer", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Compiler.Specializer.pas" }, { "name": "Myc.Ast.Environment", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Environment.pas" }, { "name": "Myc.Ast.Debugger", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Debugger.pas" }, { "name": "Myc.Ast.Analysis.Purity", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Analysis.Purity.pas" }, { "name": "Myc.Ast.Identities", "file": "file:///T%3A/Myc/Src/AST/Myc.Ast.Identities.pas" }, { "name": "Myc.Fmx.AstEditor.Handlers", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Handlers.pas" }, { "name": "Myc.Fmx.AstEditor.Visualizer", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Visualizer.pas" }, { "name": "Myc.Fmx.AstEditor.Workspace", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Workspace.pas" }, { "name": "Myc.Fmx.AstEditor.Controller", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Controller.pas" }, { "name": "Myc.Fmx.AstEditor", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.pas" }, { "name": "Myc.Fmx.AstEditor.Layout", "file": "file:///T%3A/Myc/Src/AST/Myc.Fmx.AstEditor.Layout.pas" } ] , "includeDCUsInUsesCompletion": true, "enableKeyWordCompletion": false, "browsingPaths": [ "file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/OCX/Servers","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/SOURCE/VCL","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/rtl/common","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/SOURCE/RTL/SYS","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/rtl/win","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/rtl/win/winrt","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/ToolsAPI","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/SOURCE/IBX","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/Internet","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/SOURCE/PROPERTY%20EDITORS","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/soap","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/SOURCE/XML","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/Indy10/Core","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/Indy10/System","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/Indy10/Protocols","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/fmx","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/databinding/components","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/databinding/engine","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/databinding/graph","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/ado","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/cloud","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/datasnap","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/dbx","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/dsnap","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/vclctrls","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/datasnap/connectors","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/datasnap/proxygen","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DataExplorer","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/Contrib/DUnitWizard/Source/Common","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/Contrib/DUnitWizard/Source/Common/dunit","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/Contrib/DUnitWizard/Source/DelphiExperts/Common","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/Contrib/DUnitWizard/Source/DelphiExperts/DUnitProject","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/Contrib/DUnitWizard/Source/DelphiExperts/DUnitProject/dunit","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/src","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/tests","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/Experts","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/indy/abstraction","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/indy/implementation","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/indyimpl","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/Property%20Editors/Indy10","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/soap/wsdlimporter","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/Visualizers","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/Contrib/XMLReporting","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnit/Contrib/XPGen","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/rest","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/firedac","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/tethering","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/DUnitX","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/data/ems","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/rtl/net","file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/source/FlatBox2D","file:///C%3A/Users/Public/Documents/Embarcadero/Studio/37.0/Dcp/%25PLATFORM%25","file:///%25TP%25/runtime/vcl","file:///S%3A/sc_famos_src/svn_vcl/cpxedits","file:///S%3A/sc_famos_src/svn_vcl/dzChart","file:///S%3A/sc_famos_src/svn_vcl/eaeditor","file:///S%3A/sc_famos_src/svn_vcl/FamosEvents","file:///S%3A/sc_famos_src/svn_vcl/HTML_Viewer/source","file:///S%3A/sc_famos_src/svn_vcl/Myc_ChartEdit","file:///S%3A/sc_famos_src/svn_vcl/Myc_HemiDrag","file:///S%3A/sc_famos_src/svn_vcl/Myc_SplitControl","file:///S%3A/sc_famos_src/svn_vcl/NiceChart","file:///S%3A/sc_famos_src/svn_vcl/plotter","file:///S%3A/sc_famos_src/svn_vcl/SimpleIPC","file:///S%3A/sc_famos_src/svn_vcl/SynEdit-master/Source","file:///S%3A/sc_famos_src/svn_vcl/ValEdits","file:///S%3A/sc_famos_src/svn_vcl/ZipMaster","file:///S%3A/sc_famos_src/svn_vcl/ZipMaster/zlib","file:///S%3A/sc_famos_src/svn_vcl/ZipMaster/zlib/win32","file:///S%3A/sc_famos_src/svn_vcl/Virtual-TreeView/Source","file:///S%3A/sc_famos_src/svn_common/caHelpSys","file:///S%3A/sc_famos_src/svn_common/Misc","file:///S%3A/sc_famos_src/svn_common/Myc_VecMath","file:///S%3A/sc_famos_src/svn_common/PascalScript/source","file:///S%3A/sc_famos_src/svn_common/TreeBase","file:///S%3A/sc_famos_src/svn_common/TreeBase/Medien","file:///S%3A/3rdParty/spring4d/Source","file:///S%3A/3rdParty/spring4d/Source/Base","file:///S%3A/3rdParty/spring4d/Source/Base/Collections","file:///S%3A/3rdParty/spring4d/Source/Base/Logging","file:///S%3A/3rdParty/spring4d/Source/Base/Patches","file:///S%3A/3rdParty/spring4d/Source/Core/Container","file:///S%3A/3rdParty/spring4d/Source/Core/Interception","file:///S%3A/3rdParty/spring4d/Source/Core/Logging","file:///S%3A/3rdParty/spring4d/Source/Core/Mocking","file:///S%3A/3rdParty/spring4d/Source/Core/Services","file:///S%3A/3rdParty/spring4d/Source/Extensions/Cryptography","file:///S%3A/3rdParty/spring4d/Source/Extensions/Utils","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressCore%20Library/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressCommon%20Library/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressGDI%2B%20Library/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressLibrary/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/XP%20Theme%20Manager/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressLayout%20Control/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressPageControl/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressEditors%20Library/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressDocking%20Library/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressBars/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressOfficeCore%20Library/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressMemData/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressDataController/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressNavBar/Sources","file:///C%3A/Program%20Files%20%28x86%29/DevExpress%20VCL/ExpressSkins%20Library/Sources","file:///T%3A/Myc/Src","file:///T%3A/Myc/Src/Data","file:///T%3A/Myc/Src/AST" ] , "CommonAppData": "file:///C%3A/Users/Brummel/AppData/Roaming/Embarcadero/BDS/37.0/" , "Templates": "file:///c%3A/program%20files%20%28x86%29/embarcadero/studio/37.0/ObjRepos/" } } \ No newline at end of file diff --git a/ASTPlayground/ASTPlayground.dpr b/ASTPlayground/ASTPlayground.dpr index c9dc79e..73bb958 100644 --- a/ASTPlayground/ASTPlayground.dpr +++ b/ASTPlayground/ASTPlayground.dpr @@ -30,7 +30,8 @@ uses Myc.Fmx.AstEditor.Visualizer in '..\Src\AST\Myc.Fmx.AstEditor.Visualizer.pas', Myc.Fmx.AstEditor.Workspace in '..\Src\AST\Myc.Fmx.AstEditor.Workspace.pas', Myc.Fmx.AstEditor.Controller in '..\Src\AST\Myc.Fmx.AstEditor.Controller.pas', - Myc.Fmx.AstEditor in '..\Src\AST\Myc.Fmx.AstEditor.pas'; + Myc.Fmx.AstEditor in '..\Src\AST\Myc.Fmx.AstEditor.pas', + Myc.Fmx.AstEditor.Layout in '..\Src\AST\Myc.Fmx.AstEditor.Layout.pas'; {$R *.res} diff --git a/ASTPlayground/ASTPlayground.dproj b/ASTPlayground/ASTPlayground.dproj index dbfe0b7..2a24462 100644 --- a/ASTPlayground/ASTPlayground.dproj +++ b/ASTPlayground/ASTPlayground.dproj @@ -161,6 +161,7 @@ + Base diff --git a/ASTPlayground/MainForm.pas b/ASTPlayground/MainForm.pas index e32cb62..ef802ec 100644 --- a/ASTPlayground/MainForm.pas +++ b/ASTPlayground/MainForm.pas @@ -119,7 +119,7 @@ type FCurrUnboundAst: IAstNode; FCurrExec: TCompiledFunction; FEnvironment: TAstEnvironment; - FWorkspace: TAstWorkspace; + FWorkspace: TWorkspace; // Changed to TWorkspace FController: TAstEditorController; // The UI Controller FScriptUpdate: Boolean; FTriggerTest: TAstEnvironment; @@ -159,13 +159,15 @@ begin FEnvironment := TAstEnvironment.Construct(TAst.CreateScope(nil)); // 2. Initialize Workspace - FWorkspace := TAstWorkspace.Create(Panel2); + // TWorkspace is now a simple viewport control + FWorkspace := TWorkspace.Create(Panel2); FWorkspace.Parent := Panel2; FWorkspace.Align := TAlignLayout.Client; FWorkspace.ClipChildren := true; FWorkspace.OnMouseDown := WorkspaceMouseDown; // 3. Initialize Controller (connects Env and Workspace) + // The Controller will manage the nodes inside FWorkspace.World FController := TAstEditorController.Create(FEnvironment, FWorkspace); // 4. Register the SMA factory into the environment @@ -295,6 +297,7 @@ begin exit; // Use the Controller to build, validate and show the UI + // The controller internally clears FWorkspace.World and adds nodes there. FController.SetRoot(FCurrUnboundAst); end; @@ -419,8 +422,9 @@ end; procedure TForm1.ClearButtonClick(Sender: TObject); begin - FWorkspace.DeleteChildren; - FWorkspace.Repaint; + // Clear content of world (not workspace itself, as it has the root layer) + FWorkspace.World.DeleteChildren; + FWorkspace.World.Repaint; end; procedure TForm1.CompilerStageBoxChange(Sender: TObject); @@ -886,8 +890,8 @@ procedure TForm1.UpdateScript; begin PrintScript(FCurrUnboundAst); - FWorkspace.DeleteChildren; - ShowVizualization(14, 14); + // Clear and redraw via Controller + FController.SetRoot(FCurrUnboundAst); end; procedure TForm1.WorkspaceMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single); @@ -897,9 +901,6 @@ begin ShowVizualization(X, Y); end; -// ... Copy of the rest of the file logic (Save, Load, Dump, etc.) ... -// To ensure completeness, here are the remaining methods: - procedure TForm1.SaveUserLibButtonClick(Sender: TObject); var rootNode: IAstNode; diff --git a/Src/AST/Myc.Fmx.AstEditor.Controller.pas b/Src/AST/Myc.Fmx.AstEditor.Controller.pas index 9c8ae2e..c06b429 100644 --- a/Src/AST/Myc.Fmx.AstEditor.Controller.pas +++ b/Src/AST/Myc.Fmx.AstEditor.Controller.pas @@ -6,7 +6,9 @@ uses System.SysUtils, System.Classes, System.Types, + System.Math.Vectors, System.Generics.Collections, + FMX.Types, FMX.Controls, Myc.Ast, Myc.Ast.Nodes, @@ -24,13 +26,11 @@ type type TNodeMap = TDictionary; - // Visitor to propagate Type Information from TypedAST to Visual Nodes TTypePropagator = class(TAstVisitor) private FMap: TNodeMap; procedure ApplyType(const Node: IAstNode); protected - // Central hook: Called for every node during traversal procedure Accept(const Node: IAstNode); override; public constructor Create(AMap: TNodeMap); @@ -38,7 +38,7 @@ type private FEnv: TAstEnvironment; - FWorkspace: TAstWorkspace; + FWorkspace: TWorkspace; FNodeMap: TNodeMap; FRootViewNode: TAstViewNode; @@ -46,9 +46,13 @@ type procedure ClearVisuals; procedure ApplyErrors(const Log: ICompilerLog); procedure ApplyTypes(const TypedAst: IAstNode); + procedure RootResized(Sender: TObject); + + // This signature MUST match TOnDragDropEvent in Myc.Fmx.AstEditor.Workspace + procedure HandleNodeDragDrop(ASource, ATarget: TControl; AIndex: Integer); public - constructor Create(const AEnv: TAstEnvironment; AWorkspace: TAstWorkspace); + constructor Create(const AEnv: TAstEnvironment; AWorkspace: TWorkspace); destructor Destroy; override; procedure ValidateAndShow; @@ -58,40 +62,120 @@ type implementation uses - Myc.Data.Value; + Myc.Data.Value, + Myc.Fmx.AstEditor.Visualizer; { TAstEditorController } -constructor TAstEditorController.Create(const AEnv: TAstEnvironment; AWorkspace: TAstWorkspace); +constructor TAstEditorController.Create(const AEnv: TAstEnvironment; AWorkspace: TWorkspace); begin inherited Create; FEnv := AEnv; FWorkspace := AWorkspace; + // Connect the event + FWorkspace.OnNodeDragDrop := HandleNodeDragDrop; FNodeMap := TNodeMap.Create; end; destructor TAstEditorController.Destroy; begin + SetRoot(nil); FNodeMap.Free; inherited; end; -procedure TAstEditorController.SetRoot(const AstNode: IAstNode); +procedure TAstEditorController.HandleNodeDragDrop(ASource, ATarget: TControl; AIndex: Integer); +var + SourceParent: TControl; + ContainerOwner: TAstViewNode; + Reorderable: IReorderable; + SourceIdx, TargetIdx: Integer; + NewAst: IAstNode; begin - FWorkspace.DeleteChildren; - FWorkspace.Build(AstNode, TPointF.Create(50, 50)); + // Validation + if (ASource = nil) or (AIndex < 0) then + Exit; + if not (ASource is TAstViewNode) then + Exit; - if FWorkspace.ChildrenCount > 0 then + // Explicit cast to TControl to avoid TFmxObject incompatibility + if not (ASource.Parent is TControl) then + Exit; + SourceParent := TControl(ASource.Parent); + + // We need to find the ViewNode responsible for this container that implements IReorderable. + ContainerOwner := nil; + + // 1. Check if the direct parent is the ViewNode (Direct list handler scenario) + // TNodeListHandler adds items directly to the ViewNode, so SourceParent IS the ViewNode. + if (SourceParent is TAstViewNode) then begin - for var i := 0 to FWorkspace.ChildrenCount - 1 do - if FWorkspace.Children[i] is TAstViewNode then - begin - FRootViewNode := TAstViewNode(FWorkspace.Children[i]); - break; - end; + ContainerOwner := TAstViewNode(SourceParent); + // Only keep it if it actually supports reordering + if not Supports(ContainerOwner.Handler, IReorderable, Reorderable) then + ContainerOwner := nil; end; - ValidateAndShow; + // 2. Fallback: Check grandparent (Intermediate container scenario) + // Used when items are wrapped in an intermediate TAutoFitControl (e.g. by AddExpr). + if (ContainerOwner = nil) and (SourceParent.Parent is TAstViewNode) then + begin + ContainerOwner := TAstViewNode(SourceParent.Parent); + if not Supports(ContainerOwner.Handler, IReorderable, Reorderable) then + ContainerOwner := nil; + end; + + // Execute Move + if (ContainerOwner <> nil) and (Reorderable <> nil) then + begin + if Reorderable.CanDrag(ASource) then + begin + SourceIdx := ASource.Index; + TargetIdx := AIndex; + + if SourceIdx <> TargetIdx then + begin + // A. Update internal state in the Handler (modifies FChildNodes list) + Reorderable.MoveChild(SourceIdx, TargetIdx); + + // B. Rebuild UI Logic + // Since the handler's internal list is now reordered, CreateAst + // will produce a new AST with the correct order. + NewAst := FRootViewNode.CreateAst; + + // C. Full UI Refresh + // ValidateAndShow only annotates. SetRoot destroys the old visual tree + // and builds a new one from the freshly generated AST. + SetRoot(NewAst); + end; + end; + end; +end; + +procedure TAstEditorController.SetRoot(const AstNode: IAstNode); +var + Visualizer: IAstVisualizer; +begin + FWorkspace.World.DeleteChildren; + if Assigned(FRootViewNode) then + FRootViewNode.OnResized := nil; + FRootViewNode := nil; + + if not Assigned(AstNode) then + Exit; + + Visualizer := TAstVisualizer.Create(FWorkspace, FWorkspace.World, 0); + FRootViewNode := Visualizer.CallAccept(AstNode); + + if Assigned(FRootViewNode) then + begin + FWorkspace.World.Size := FRootViewNode.Size; + FRootViewNode.OnResized := RootResized; + FRootViewNode.Position.Point := TPointF.Create(50, 50); + end; + + if Assigned(FRootViewNode) then + ValidateAndShow; end; procedure TAstEditorController.CollectNodes(Parent: TControl); @@ -109,9 +193,6 @@ begin if child is TAstViewNode then begin viewNode := TAstViewNode(child); - // Register Identity -> ViewNode - // Note: ReconstructAst updates the Node property of the ViewNode, - // so we must ensure we use the identity from the *logical* node held by the view. if Assigned(viewNode.Node) and Assigned(viewNode.Node.Identity) then begin FNodeMap.AddOrSetValue(viewNode.Node.Identity, viewNode); @@ -162,13 +243,17 @@ begin propagator := TTypePropagator.Create(FNodeMap); try - // Start traversal. The overload Accept(Node) will be called. propagator.Accept(TypedAst); finally propagator.Free; end; end; +procedure TAstEditorController.RootResized(Sender: TObject); +begin + FWorkspace.World.Size := FRootViewNode.Size; +end; + procedure TAstEditorController.ValidateAndShow; var logicalAst: IAstNode; @@ -176,26 +261,18 @@ begin if not Assigned(FRootViewNode) then Exit; - // 1. Reconstruct Logical AST from UI - // This updates the .Node property on ViewNodes with fresh Identities (if configured) or reuses them. logicalAst := FRootViewNode.CreateAst; - // 2. Rebuild Mapping based on the new logical nodes FNodeMap.Clear; - CollectNodes(FWorkspace); + CollectNodes(FWorkspace.World); - // 3. Clear visuals ClearVisuals; - // 4. Compile try - // To get type info, we re-bind/check manually as Compile doesn't return the TypedAST. var log := TCompilerLog.Create as ICompilerLog; - // We need to expand macros first to match the structure Compile used var expanded := FEnv.ExpandMacros(logicalAst); var typedAst := FEnv.Bind(expanded, [], log); - var specAst := FEnv.Specialize(typedAst); ApplyTypes(specAst); @@ -214,7 +291,7 @@ begin end; end; - FWorkspace.Repaint; + FWorkspace.World.Repaint; end; { TAstEditorController.TTypePropagator } @@ -247,11 +324,7 @@ procedure TAstEditorController.TTypePropagator.Accept(const Node: IAstNode); begin if Node = nil then Exit; - - // 1. Apply side effect ApplyType(Node); - - // 2. Continue traversal (Standard TAstVisitor logic calls VisitXY which calls Accept for children) Node.Accept(Self); end; diff --git a/Src/AST/Myc.Fmx.AstEditor.Handlers.pas b/Src/AST/Myc.Fmx.AstEditor.Handlers.pas index df973b0..edfcafb 100644 --- a/Src/AST/Myc.Fmx.AstEditor.Handlers.pas +++ b/Src/AST/Myc.Fmx.AstEditor.Handlers.pas @@ -17,12 +17,13 @@ uses Myc.Ast, Myc.Ast.Nodes, Myc.Ast.Identities, + Myc.Fmx.AstEditor.Layout, Myc.Fmx.AstEditor; type // --- Abstract List Base --- - // Handles layout, brackets (from Identity), and child iteration - TNodeListHandler = class(TBaseNodeHandler>) + // Now implements IReorderable to support drag & drop reordering + TNodeListHandler = class(TBaseNodeHandler>, IReorderable) protected FChildNodes: TList; function GetOrientation: TLayoutOrientation; virtual; abstract; @@ -32,6 +33,10 @@ type destructor Destroy; override; procedure BuildUI(OwnerNode: TAstViewNode); override; function ReconstructAst(OwnerNode: TAstViewNode): IAstNode; override; abstract; + + // IReorderable Implementation + function CanDrag(Child: TControl): Boolean; + procedure MoveChild(SourceIndex, TargetIndex: Integer); end; // --- Concrete List Handlers --- @@ -352,6 +357,38 @@ begin end; end; +// IReorderable Implementation + +function TNodeListHandler.CanDrag(Child: TControl): Boolean; +begin + // Allow dragging only if the child is one of our managed ViewNodes + Result := (Child is TAstViewNode) and FChildNodes.Contains(TAstViewNode(Child)); +end; + +procedure TNodeListHandler.MoveChild(SourceIndex, TargetIndex: Integer); +var + item: TAstViewNode; +begin + if (SourceIndex < 0) or (SourceIndex >= FChildNodes.Count) then + Exit; + if (TargetIndex < 0) or (TargetIndex > FChildNodes.Count) then + Exit; + + // Adjust target index if moving downwards (since removing source shifts indices) + if SourceIndex < TargetIndex then + Dec(TargetIndex); + + if SourceIndex = TargetIndex then + Exit; + + item := FChildNodes[SourceIndex]; + FChildNodes.Delete(SourceIndex); + FChildNodes.Insert(TargetIndex, item); + + // The visual order update will happen upon the next ReconstructAst -> Compile -> BuildUI cycle + // triggered by the controller. +end; + { TParameterListHandler } function TParameterListHandler.GetOrientation: TLayoutOrientation; diff --git a/Src/AST/Myc.Fmx.AstEditor.Layout.pas b/Src/AST/Myc.Fmx.AstEditor.Layout.pas new file mode 100644 index 0000000..f260d75 --- /dev/null +++ b/Src/AST/Myc.Fmx.AstEditor.Layout.pas @@ -0,0 +1,280 @@ +unit Myc.Fmx.AstEditor.Layout; + +interface + +uses + System.SysUtils, + System.Classes, + System.Types, + System.Math, + System.Math.Vectors, + System.Generics.Collections, + FMX.Types, + FMX.Controls; + +type + TLayoutOrientation = (loVertical, loHorizontal); + TLayoutAlignment = (laCenter, laFlush); + + TAutoFitControl = class(TControl) + private + FUpdatingOwnSize: Boolean; + FNeedRecalcSize: Boolean; + FOrientation: TLayoutOrientation; + FAlignment: TLayoutAlignment; + procedure RecalcOwnSize; + procedure SetOrientation(const Value: TLayoutOrientation); + procedure SetAlignment(const Value: TLayoutAlignment); + protected + procedure ParentContentChanged; override; + procedure PaddingChanged; override; + procedure ChangeChildren; override; + procedure Loaded; override; + procedure DoEndUpdate; override; + public + constructor Create(AOwner: TComponent); override; + function GetInsertionIndex(const P: TPointF; ItemClass: TClass = nil): Integer; + + published + property Padding; + property Orientation: TLayoutOrientation read FOrientation write SetOrientation default TLayoutOrientation.loHorizontal; + property Alignment: TLayoutAlignment read FAlignment write SetAlignment default TLayoutAlignment.laCenter; + end; + +implementation + +{ TAutoFitControl } + +constructor TAutoFitControl.Create(AOwner: TComponent); +begin + inherited Create(AOwner); + HitTest := True; + FOrientation := TLayoutOrientation.loHorizontal; + FAlignment := TLayoutAlignment.laCenter; +end; + +procedure TAutoFitControl.SetAlignment(const Value: TLayoutAlignment); +begin + if FAlignment <> Value then + begin + FAlignment := Value; + RecalcOwnSize; + end; +end; + +procedure TAutoFitControl.SetOrientation(const Value: TLayoutOrientation); +begin + if FOrientation <> Value then + begin + FOrientation := Value; + RecalcOwnSize; + end; +end; + +function TAutoFitControl.GetInsertionIndex(const P: TPointF; ItemClass: TClass = nil): Integer; +var + i: Integer; + child: TControl; + center: Single; + relevantChildren: TList; +begin + relevantChildren := TList.Create; + try + for i := 0 to ChildrenCount - 1 do + begin + if Children[i] is TControl then + begin + child := TControl(Children[i]); + if child.Visible and (child.Align = TAlignLayout.None) then + begin + if (ItemClass = nil) or (child.InheritsFrom(ItemClass)) then + relevantChildren.Add(child); + end; + end; + end; + + Result := relevantChildren.Count; + + for i := 0 to relevantChildren.Count - 1 do + begin + child := relevantChildren[i]; + + if FOrientation = TLayoutOrientation.loVertical then + begin + // Fix: Robustere Erkennung. Wenn P.Y kleiner als Mitte ist -> Insert + center := child.Position.Y + (child.Height / 2); + if P.Y < center then + Exit(i); + end + else + begin + center := child.Position.X + (child.Width / 2); + if P.X < center then + Exit(i); + end; + end; + finally + relevantChildren.Free; + end; +end; + +procedure TAutoFitControl.RecalcOwnSize; +var + i: Integer; + child: TControl; + childrenToLayout: TList; + currentX, currentY: Single; + requiredWidth, requiredHeight: Single; + childWidthWithMargins, childHeightWithMargins: Single; + hasVisibleChild: Boolean; +begin + if FUpdatingOwnSize then + exit; + if IsUpdating then + begin + FNeedRecalcSize := True; + exit; + end; + + FUpdatingOwnSize := True; + childrenToLayout := nil; + try + requiredWidth := Padding.Left + Padding.Right; + requiredHeight := Padding.Top + Padding.Bottom; + currentX := Padding.Left; + currentY := Padding.Top; + hasVisibleChild := False; + + childrenToLayout := TList.Create; + for i := 0 to ChildrenCount - 1 do + begin + if Children[i] is TControl then + begin + child := TControl(Children[i]); + if child.Visible and (child.Align = TAlignLayout.None) then + begin + childrenToLayout.Add(child); + hasVisibleChild := True; + end; + end; + end; + + if hasVisibleChild then + begin + if FOrientation = TLayoutOrientation.loVertical then + begin + for child in childrenToLayout do + begin + child.Position.Y := currentY + child.Margins.Top; + currentY := child.Position.Y + child.Height + child.Margins.Bottom; + + childWidthWithMargins := Padding.Left + child.Margins.Left + child.Width + child.Margins.Right + Padding.Right; + requiredWidth := System.Math.Max(requiredWidth, childWidthWithMargins); + end; + requiredHeight := currentY + Padding.Bottom; + + if FAlignment = TLayoutAlignment.laFlush then + begin + for child in childrenToLayout do + begin + child.Position.X := Padding.Left + child.Margins.Left; + end; + end + else + begin + var contentWidth := requiredWidth - Padding.Left - Padding.Right; + for child in childrenToLayout do + begin + var childTotalWidth := child.Width + child.Margins.Left + child.Margins.Right; + var childX := Padding.Left + ((contentWidth - childTotalWidth) / 2) + child.Margins.Left; + child.Position.X := childX; + end; + end; + end + else + begin + for child in childrenToLayout do + begin + child.Position.X := currentX + child.Margins.Left; + currentX := child.Position.X + child.Width + child.Margins.Right; + + childHeightWithMargins := Padding.Top + child.Margins.Top + child.Height + child.Margins.Bottom + Padding.Bottom; + requiredHeight := System.Math.Max(requiredHeight, childHeightWithMargins); + end; + requiredWidth := currentX + Padding.Right; + + if FAlignment = TLayoutAlignment.laFlush then + begin + for child in childrenToLayout do + begin + child.Position.Y := Padding.Top + child.Margins.Top; + end; + end + else + begin + var contentHeight := requiredHeight - Padding.Top - Padding.Bottom; + for child in childrenToLayout do + begin + var childTotalHeight := child.Height + child.Margins.Top + child.Margins.Bottom; + var childY := Padding.Top + ((contentHeight - childTotalHeight) / 2) + child.Margins.Top; + child.Position.Y := childY; + end; + end; + end; + end + else + begin + requiredWidth := Padding.Left + Padding.Right; + requiredHeight := Padding.Top + Padding.Bottom; + end; + + requiredWidth := System.Math.Max(0, requiredWidth); + requiredHeight := System.Math.Max(0, requiredHeight); + + if not SameValue(requiredWidth, Width, TEpsilon.Position) or not SameValue(requiredHeight, Height, TEpsilon.Position) then + begin + FSize.SetSizeWithoutNotification(TSizeF.Create(requiredWidth, requiredHeight)); + HandleSizeChanged; + end; + + finally + childrenToLayout.Free; + FUpdatingOwnSize := False; + end; +end; + +procedure TAutoFitControl.Loaded; +begin + inherited Loaded; + RecalcOwnSize; +end; + +procedure TAutoFitControl.ChangeChildren; +begin + inherited ChangeChildren; + RecalcOwnSize; +end; + +procedure TAutoFitControl.PaddingChanged; +begin + inherited PaddingChanged; + RecalcOwnSize; +end; + +procedure TAutoFitControl.ParentContentChanged; +begin + inherited ParentContentChanged; + RecalcOwnSize; +end; + +procedure TAutoFitControl.DoEndUpdate; +begin + inherited; + if FNeedRecalcSize then + begin + FNeedRecalcSize := False; + RecalcOwnSize; + end; +end; + +end. diff --git a/Src/AST/Myc.Fmx.AstEditor.Visualizer.pas b/Src/AST/Myc.Fmx.AstEditor.Visualizer.pas index 4f5cd3e..6f3388c 100644 --- a/Src/AST/Myc.Fmx.AstEditor.Visualizer.pas +++ b/Src/AST/Myc.Fmx.AstEditor.Visualizer.pas @@ -19,11 +19,11 @@ type private FExprDepth: Integer; FParentControl: TControl; - FWorkspace: TAstWorkspace; + FWorkspace: TWorkspace; // Changed from TAstWorkspace to TWorkspace function CallAccept(const Node: IAstNode): TAstViewNode; function GetExprDepth: Integer; function GetParentControl: TControl; - function GetWorkspace: TAstWorkspace; + function GetWorkspace: TWorkspace; // Changed signature procedure SetExprDepth(const Value: Integer); procedure SetParentControl(const Value: TControl); protected @@ -61,21 +61,21 @@ type function VisitNop(const Node: INopNode): TAstViewNode; override; public - constructor Create(AWorkspace: TAstWorkspace; AParentControl: TControl; AExprDepth: Integer); + constructor Create(AWorkspace: TWorkspace; AParentControl: TControl; AExprDepth: Integer); destructor Destroy; override; function Clone(ParentControl: TControl; ExprDepth: Integer): IAstVisualizer; property ExprDepth: Integer read GetExprDepth write SetExprDepth; property ParentControl: TControl read GetParentControl write SetParentControl; - property Workspace: TAstWorkspace read GetWorkspace; + property Workspace: TWorkspace read GetWorkspace; end; implementation { TAstVisualizer } -constructor TAstVisualizer.Create(AWorkspace: TAstWorkspace; AParentControl: TControl; AExprDepth: Integer); +constructor TAstVisualizer.Create(AWorkspace: TWorkspace; AParentControl: TControl; AExprDepth: Integer); begin inherited Create; FWorkspace := AWorkspace; @@ -122,7 +122,7 @@ begin Result := FParentControl; end; -function TAstVisualizer.GetWorkspace: TAstWorkspace; +function TAstVisualizer.GetWorkspace: TWorkspace; begin Result := FWorkspace; end; diff --git a/Src/AST/Myc.Fmx.AstEditor.Workspace.pas b/Src/AST/Myc.Fmx.AstEditor.Workspace.pas index e1c4068..d9b20a4 100644 --- a/Src/AST/Myc.Fmx.AstEditor.Workspace.pas +++ b/Src/AST/Myc.Fmx.AstEditor.Workspace.pas @@ -3,302 +3,484 @@ unit Myc.Fmx.AstEditor.Workspace; interface uses - System.SysUtils, System.Classes, + System.SysUtils, System.Types, System.UITypes, + System.Math, System.Math.Vectors, - System.Generics.Collections, FMX.Types, FMX.Controls, - FMX.Graphics, FMX.Objects, - Myc.Ast.Nodes; - -const - cDataPinColor = TAlphaColors.Dodgerblue; - cExecPinColor = TAlphaColors.Lightgreen; + FMX.Graphics, + FMX.Forms, + Myc.Fmx.AstEditor.Layout; type - TPinConnection = record - OutputPin: TControl; - InputPin: TControl; - constructor Create(AOutputPin, AInputPin: TControl); - end; + TOnPaintConnectionsEvent = procedure(ASender: TObject; ACanvas: TCanvas) of object; - TAstWorkspace = class(TStyledControl) + TOnDragDropEvent = procedure(ASource, ATarget: TControl; AIndex: Integer) of object; + + TAstWorld = class(TControl) private - FConnections: TArray; - FPanning: TSizeF; - FIsPanning: Boolean; - FLastPanPos: TPointF; - FZoom: Single; + FOnPaintConnections: TOnPaintConnectionsEvent; + // VISUAL: Drop Marker State + FShowDropMarker: Boolean; + FDropP1, FDropP2: TPointF; protected procedure Paint; override; - procedure DoDeleteChildren; override; + procedure AfterPaint; override; // <--- HIER: Für Zeichnen ÜBER den Kindern + public + constructor Create(AOwner: TComponent); override; + procedure InvalidateConnections; + property OnPaintConnections: TOnPaintConnectionsEvent read FOnPaintConnections write FOnPaintConnections; + end; + + TWorkspace = class(TControl) + private + const + MinZoom = 0.1; + MaxZoom = 5.0; + ZoomStep = 0.1; + private + FRootLayer: TAstWorld; + FIsPanning: Boolean; + FLastMousePos: TPointF; + + FIsDraggingNode: Boolean; + FDragSource: TControl; + FDragVisual: TControl; + FDragOffset: TPointF; + + FCurrentDropTarget: TControl; + FCurrentDropIndex: Integer; + + FOnNodeDragDrop: TOnDragDropEvent; + + function GetZoom: Single; + procedure SetZoom(const Value: Single); + function GetContentOffset: TPointF; + procedure SetContentOffset(const Value: TPointF); + function GetOnPaintConnections: TOnPaintConnectionsEvent; + procedure SetOnPaintConnections(const Value: TOnPaintConnectionsEvent); + + procedure StopDrag; + procedure UpdateDropMarker(const ScreenPos: TPointF); + protected + procedure Loaded; override; procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Single); override; procedure MouseMove(Shift: TShiftState; X, Y: Single); override; procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Single); override; procedure MouseWheel(Shift: TShiftState; WheelDelta: Integer; var Handled: Boolean); override; - procedure DblClick; override; public constructor Create(AOwner: TComponent); override; - procedure Build(const RootNode: IAstNode; const Position: TPointF); - function GetChildrenMatrix(var Matrix: TMatrix; var Simple: Boolean): Boolean; override; - function Zoom(Factor: Single): Boolean; + destructor Destroy; override; - // Neue Public Methoden, damit Nodes das Panning steuern können - procedure ExternalMouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Single); - procedure ExternalMouseMove(Shift: TShiftState; X, Y: Single); - procedure ExternalMouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Single); + function ScreenToWorld(const APoint: TPointF): TPointF; + procedure BeginDragNode(ASource: TControl); - published - property Align; - property Anchors; - property ClipChildren default True; - property Cursor default crDefault; - property DragMode default TDragMode.dmManual; - property Enabled; - property Height; - property HelpContext; - property HelpKeyword; - property HelpType; - property Hint; - property HitTest default True; - property Locked; - property Margins; - property Opacity; - property Padding; - property PopupMenu; - property Position; - property RotationAngle; - property RotationCenter; - property Scale; - property Size; - property StyleLookup; - property Visible; - property Width; - property OnClick; - property OnDblClick; - property OnMouseDown; - property OnMouseMove; - property OnMouseUp; - property OnMouseWheel; - property OnMouseEnter; - property OnMouseLeave; + property World: TAstWorld read FRootLayer; + property Zoom: Single read GetZoom write SetZoom; + property ContentOffset: TPointF read GetContentOffset write SetContentOffset; + property OnPaintConnections: TOnPaintConnectionsEvent read GetOnPaintConnections write SetOnPaintConnections; + + property OnNodeDragDrop: TOnDragDropEvent read FOnNodeDragDrop write FOnNodeDragDrop; end; implementation -uses - System.Math, - FMX.Platform, - Myc.Fmx.AstEditor, - Myc.Fmx.AstEditor.Visualizer; +{ TAstWorld } -{ TPinConnection } - -constructor TPinConnection.Create(AOutputPin, AInputPin: TControl); -begin - OutputPin := AOutputPin; - InputPin := AInputPin; -end; - -{ TAstWorkspace } - -constructor TAstWorkspace.Create(AOwner: TComponent); +constructor TAstWorld.Create(AOwner: TComponent); begin inherited; - FZoom := 1.0; - // Standard-Eigenschaften für einen Arbeitsbereich - ClipChildren := True; - HitTest := True; + HitTest := False; + Locked := True; + Stored := False; + ClipChildren := False; + Width := 100; + Height := 100; + FShowDropMarker := False; end; -procedure TAstWorkspace.Build(const RootNode: IAstNode; const Position: TPointF); +procedure TAstWorld.Paint; +begin + inherited; + if (csDesigning in ComponentState) then + DrawDesignBorder; + + // Connections should be BEHIND the nodes, so Paint is the correct place. + if Assigned(FOnPaintConnections) then + FOnPaintConnections(Self, Canvas); +end; + +procedure TAstWorld.AfterPaint; var - visu: IAstVisualizer; - node: TAstViewNode; + ScaleFactor: Single; + Radius: Single; + Thickness: Single; begin - // Löscht alle bestehenden visuellen Knoten - DeleteChildren; - FConnections := nil; + inherited; - if not Assigned(RootNode) then - Exit; - - // Erstellt den Visualizer mit dem Workspace als Kontext - visu := TAstVisualizer.Create(Self, Self, 0); - node := visu.CallAccept(RootNode); - if Assigned(node) then + // --- DRAW DROP MARKER (IN FRONT OF NODES) --- + if FShowDropMarker then begin - node.Position.Point := Position; + // Calculate visual sizes inversely proportional to zoom + if Scale.X > 0 then + ScaleFactor := 1 / Scale.X + else + ScaleFactor := 1; + + Thickness := 3 * ScaleFactor; + Radius := 4 * ScaleFactor; + + Canvas.Stroke.Kind := TBrushKind.Solid; + Canvas.Stroke.Color := TAlphaColors.Red; + Canvas.Stroke.Thickness := Thickness; + Canvas.Stroke.Cap := TStrokeCap.Round; + + // Draw Line + Canvas.DrawLine(FDropP1, FDropP2, 1.0); + + // Draw Circles at ends + Canvas.Fill.Kind := TBrushKind.Solid; + Canvas.Fill.Color := TAlphaColors.Red; + + Canvas.FillEllipse(TRectF.Create(FDropP1.X - Radius, FDropP1.Y - Radius, FDropP1.X + Radius, FDropP1.Y + Radius), 1.0); + Canvas.FillEllipse(TRectF.Create(FDropP2.X - Radius, FDropP2.Y - Radius, FDropP2.X + Radius, FDropP2.Y + Radius), 1.0); end; end; -procedure TAstWorkspace.DoDeleteChildren; +procedure TAstWorld.InvalidateConnections; begin - FConnections := nil; - inherited; -end; - -function TAstWorkspace.GetChildrenMatrix(var Matrix: TMatrix; var Simple: Boolean): Boolean; -begin - Matrix := TMatrix.CreateScaling(FZoom, FZoom) * TMatrix.CreateTranslation(FPanning.cx, FPanning.cy); - Simple := (FZoom = 1.0) and (FPanning.cx = 0) and (FPanning.cy = 0); - Result := True; -end; - -// --- Interne Event Handler --- - -procedure TAstWorkspace.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Single); -begin - inherited; - ExternalMouseDown(Button, Shift, X, Y); -end; - -procedure TAstWorkspace.MouseMove(Shift: TShiftState; X, Y: Single); -begin - inherited; - ExternalMouseMove(Shift, X, Y); -end; - -procedure TAstWorkspace.MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Single); -begin - inherited; - ExternalMouseUp(Button, Shift, X, Y); -end; - -// --- Externe Steuerung für Nodes --- - -procedure TAstWorkspace.ExternalMouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Single); -begin - if (Button = TMouseButton.mbLeft) then - begin - Capture; - FIsPanning := True; - FLastPanPos := TPointF.Create(X, Y); - Cursor := crHandPoint; - end; -end; - -procedure TAstWorkspace.ExternalMouseMove(Shift: TShiftState; X, Y: Single); -var - delta: TPointF; -begin - if FIsPanning then - begin - delta := TPointF.Create(X - FLastPanPos.X, Y - FLastPanPos.Y); - FPanning.cx := FPanning.cx + delta.X; - FPanning.cy := FPanning.cy + delta.Y; - FLastPanPos := TPointF.Create(X, Y); - RecalcAbsolute; - RecalcUpdateRect; - Repaint; - end; -end; - -procedure TAstWorkspace.ExternalMouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Single); -begin - if (Button = TMouseButton.mbLeft) and (FIsPanning) then - begin - ReleaseCapture; - FIsPanning := False; - Cursor := crDefault; - end; -end; - -procedure TAstWorkspace.MouseWheel(Shift: TShiftState; WheelDelta: Integer; var Handled: Boolean); -begin - inherited; - Handled := Zoom(IfThen(WheelDelta > 0, FZoom * 1.1, FZoom / 1.1)); -end; - -procedure TAstWorkspace.DblClick; -begin - inherited; - // Reset Zoom/Pan on double click - FZoom := 1.0; - FPanning := TSizeF.Create(0, 0); - RecalcAbsolute; - RecalcUpdateRect; Repaint; end; -procedure TAstWorkspace.Paint; +{ TWorkspace } + +constructor TWorkspace.Create(AOwner: TComponent); +begin + inherited Create(AOwner); + ClipChildren := True; + HitTest := True; + + FRootLayer := TAstWorld.Create(Self); + FRootLayer.Parent := Self; + FRootLayer.SetBounds(0, 0, 100, 100); + FRootLayer.Scale.Point := TPointF.Create(1, 1); +end; + +destructor TWorkspace.Destroy; +begin + inherited; +end; + +procedure TWorkspace.Loaded; +begin + inherited; + if FRootLayer <> nil then + FRootLayer.BringToFront; +end; + +function TWorkspace.ScreenToWorld(const APoint: TPointF): TPointF; +begin + Result := ScreenToLocal(APoint); + Result := FRootLayer.AbsoluteToLocal(LocalToAbsolute(Result)); +end; + +procedure TWorkspace.BeginDragNode(ASource: TControl); var - connection: TPinConnection; - startPoint, endPoint, pinCenter: TPointF; - path: TPathData; - controlPoint1, controlPoint2: TPointF; - controlOffset: Single; - absoluteStart, absoluteEnd: TPointF; - str: string; + Snapshot: TBitmap; + DragImg: TImage; + MouseWorld: TPointF; + AbsPos, WorldPos: TPointF; +begin + if FIsDraggingNode or FIsPanning then + Exit; + + FIsDraggingNode := True; + FDragSource := ASource; + Root.Captured := Self; + + Snapshot := ASource.MakeScreenshot; + + DragImg := TImage.Create(nil); + DragImg.Parent := FRootLayer; + DragImg.Bitmap := Snapshot; + DragImg.WrapMode := TImageWrapMode.Stretch; + DragImg.HitTest := False; + DragImg.Opacity := 0.7; + DragImg.BringToFront; + + AbsPos := ASource.LocalToAbsolute(TPointF.Zero); + WorldPos := FRootLayer.AbsoluteToLocal(AbsPos); + + DragImg.SetBounds(WorldPos.X, WorldPos.Y, ASource.Width, ASource.Height); + FDragVisual := DragImg; + + MouseWorld := ScreenToWorld(Screen.MousePos); + FDragOffset := MouseWorld - WorldPos; + + ASource.Opacity := 0.4; +end; + +procedure TWorkspace.UpdateDropMarker(const ScreenPos: TPointF); +var + Obj: IControl; + TargetCtrl: TControl; + TargetLocalPos: TPointF; + IsHorizontal: Boolean; + InsertAfter: Boolean; + PTL, PBR: TPointF; + P1, P2: TPointF; + SourceParent: TControl; + TargetContainer: TAutoFitControl; +begin + FRootLayer.FShowDropMarker := False; + FCurrentDropTarget := nil; + FCurrentDropIndex := -1; + + if FDragSource = nil then + Exit; + + if not (FDragSource.Parent is TControl) then + Exit; + SourceParent := TControl(FDragSource.Parent); + + // 1. Find Drop Target + Obj := ObjectAtPoint(ScreenPos); + if (Obj = nil) or not (Obj.GetObject is TControl) then + Exit; + + TargetCtrl := TControl(Obj.GetObject); + + // 2. Walk up hierarchy + while (TargetCtrl <> nil) and (TargetCtrl.Parent <> SourceParent) do + begin + TargetCtrl := TargetCtrl.ParentControl; + if TargetCtrl = FRootLayer then + Exit; + end; + + if TargetCtrl = nil then + Exit; + if TargetCtrl = FDragSource then + Exit; + + FCurrentDropTarget := TargetCtrl; + + // 3. Determine Geometry using TAutoFitControl info + TargetLocalPos := TargetCtrl.AbsoluteToLocal(ScreenPos); + + IsHorizontal := True; // Default fallback + + if SourceParent is TAutoFitControl then + begin + TargetContainer := TAutoFitControl(SourceParent); + + if TargetContainer.Orientation = TLayoutOrientation.loHorizontal then + IsHorizontal := True + else + IsHorizontal := False; + end; + + // Split logic + if IsHorizontal then + InsertAfter := TargetLocalPos.X > (TargetCtrl.Width / 2) + else + InsertAfter := TargetLocalPos.Y > (TargetCtrl.Height / 2); + + // 4. Calculate Index + if InsertAfter then + FCurrentDropIndex := TargetCtrl.Index + 1 + else + FCurrentDropIndex := TargetCtrl.Index; + + // 5. Calculate Marker Visuals + var AbsTL := TargetCtrl.LocalToAbsolute(TPointF.Zero); + var AbsBR := TargetCtrl.LocalToAbsolute(TPointF.Create(TargetCtrl.Width, TargetCtrl.Height)); + + PTL := FRootLayer.AbsoluteToLocal(AbsTL); + PBR := FRootLayer.AbsoluteToLocal(AbsBR); + + if IsHorizontal then + begin + // Vertical Line + var XPos := PTL.X; + if InsertAfter then + XPos := PBR.X; + + if InsertAfter then + XPos := XPos + 2 + else + XPos := XPos - 2; + + P1 := TPointF.Create(XPos, PTL.Y); + P2 := TPointF.Create(XPos, PBR.Y); + end + else + begin + // Horizontal Line + var YPos := PTL.Y; + if InsertAfter then + YPos := PBR.Y; + + if InsertAfter then + YPos := YPos + 2 + else + YPos := YPos - 2; + + P1 := TPointF.Create(PTL.X, YPos); + P2 := TPointF.Create(PBR.X, YPos); + end; + + FRootLayer.FDropP1 := P1; + FRootLayer.FDropP2 := P2; + FRootLayer.FShowDropMarker := True; +end; + +procedure TWorkspace.StopDrag; +begin + if not FIsDraggingNode then + Exit; + + if Assigned(FDragVisual) then + begin + FDragVisual.Parent := nil; + FDragVisual.Free; + FDragVisual := nil; + end; + + if Assigned(FDragSource) then + FDragSource.Opacity := 1.0; + + FRootLayer.FShowDropMarker := False; + FRootLayer.Repaint; + + if Assigned(FOnNodeDragDrop) and Assigned(FCurrentDropTarget) and (FCurrentDropIndex >= 0) then + FOnNodeDragDrop(FDragSource, FCurrentDropTarget, FCurrentDropIndex); + + FIsDraggingNode := False; + FDragSource := nil; + FCurrentDropTarget := nil; + Root.Captured := nil; +end; + +procedure TWorkspace.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Single); +begin + inherited; + if not FIsDraggingNode and (Button in [TMouseButton.mbLeft, TMouseButton.mbMiddle]) then + begin + FIsPanning := True; + FLastMousePos := TPointF.Create(X, Y); + Root.Captured := Self; + end; +end; + +procedure TWorkspace.MouseMove(Shift: TShiftState; X, Y: Single); +var + LCurrentPos: TPointF; + LDelta: TPointF; + LWorldPos: TPointF; begin inherited; - Canvas.Stroke.Kind := TBrushKind.Solid; - Canvas.Stroke.Thickness := 2; - - for connection in FConnections do + if FIsDraggingNode then begin - // Safety check if pins are still valid/visible - if (connection.OutputPin = nil) - or (connection.InputPin = nil) - or (connection.OutputPin.Root <> Self.Root) - or (connection.InputPin.Root <> Self.Root) then - continue; - - pinCenter := TPointF.Create(connection.OutputPin.Width / 2, connection.OutputPin.Height / 2); - absoluteStart := connection.OutputPin.LocalToAbsolute(pinCenter); - - pinCenter := TPointF.Create(connection.InputPin.Width / 2, connection.InputPin.Height / 2); - absoluteEnd := connection.InputPin.LocalToAbsolute(pinCenter); - - startPoint := AbsoluteToLocal(absoluteStart); - endPoint := AbsoluteToLocal(absoluteEnd); - - str := connection.InputPin.TagString; - if Pos('data', str) = 0 then - Canvas.Stroke.Color := cExecPinColor - else - Canvas.Stroke.Color := cDataPinColor; - - path := TPathData.Create; - try - controlOffset := Max(25, 0.5 * endPoint.Distance(startPoint)); - controlPoint1 := TPointF.Create(startPoint.X + controlOffset, startPoint.Y); - controlPoint2 := TPointF.Create(endPoint.X - controlOffset, endPoint.Y); - path.MoveTo(startPoint); - path.CurveTo(controlPoint1, controlPoint2, endPoint); - Canvas.DrawPath(path, 1.0); - finally - path.Free; + if Assigned(FDragVisual) then + begin + LWorldPos := ScreenToWorld(Screen.MousePos); + FDragVisual.Position.Point := LWorldPos - FDragOffset; end; + + UpdateDropMarker(Screen.MousePos); + + FRootLayer.Repaint; + end + else if FIsPanning then + begin + LCurrentPos := TPointF.Create(X, Y); + LDelta := LCurrentPos - FLastMousePos; + + FRootLayer.Position.Point := FRootLayer.Position.Point + LDelta; + + FLastMousePos := LCurrentPos; end; end; -function TAstWorkspace.Zoom(Factor: Single): Boolean; -var - mouseService: IFMXMouseService; - mousePos: TPointF; +procedure TWorkspace.MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Single); begin - Result := TPlatformServices.Current.SupportsPlatformService(IFMXMouseService, mouseService); - if Result then + inherited; + if FIsDraggingNode then begin - mousePos := ScreenToLocal(mouseService.GetMousePos); - Factor := Max(0.2, Min(3.0, Factor)); - - // Adjust panning to zoom towards mouse position - FPanning.cx := mousePos.X * (1 - Factor / FZoom) + FPanning.cx * (Factor / FZoom); - FPanning.cy := mousePos.Y * (1 - Factor / FZoom) + FPanning.cy * (Factor / FZoom); - - FZoom := Factor; - - RecalcAbsolute; - RecalcUpdateRect; - Repaint; + StopDrag; + end + else if FIsPanning then + begin + FIsPanning := False; + Root.Captured := nil; end; end; +procedure TWorkspace.MouseWheel(Shift: TShiftState; WheelDelta: Integer; var Handled: Boolean); +var + LOldZoom, LNewZoom: Single; + LScaleRatio: Single; + LMousePosLocal: TPointF; + LOffset: TPointF; +begin + LOldZoom := Zoom; + + if WheelDelta > 0 then + LNewZoom := LOldZoom + ZoomStep + else + LNewZoom := LOldZoom - ZoomStep; + + LNewZoom := EnsureRange(LNewZoom, MinZoom, MaxZoom); + + if not SameValue(LNewZoom, LOldZoom, TEpsilon.Vector) then + begin + LMousePosLocal := ScreenToLocal(Screen.MousePos); + LOffset := LMousePosLocal - FRootLayer.Position.Point; + LScaleRatio := LNewZoom / LOldZoom; + + FRootLayer.Position.Point := LMousePosLocal - (LOffset * LScaleRatio); + SetZoom(LNewZoom); + end; + Handled := True; + + if not Handled then + inherited; +end; + +function TWorkspace.GetZoom: Single; +begin + Result := FRootLayer.Scale.X; +end; + +procedure TWorkspace.SetZoom(const Value: Single); +begin + FRootLayer.Scale.Point := TPointF.Create(Value, Value); +end; + +function TWorkspace.GetContentOffset: TPointF; +begin + Result := FRootLayer.Position.Point; +end; + +procedure TWorkspace.SetContentOffset(const Value: TPointF); +begin + FRootLayer.Position.Point := Value; +end; + +function TWorkspace.GetOnPaintConnections: TOnPaintConnectionsEvent; +begin + Result := FRootLayer.OnPaintConnections; +end; + +procedure TWorkspace.SetOnPaintConnections(const Value: TOnPaintConnectionsEvent); +begin + FRootLayer.OnPaintConnections := Value; +end; + end. diff --git a/Src/AST/Myc.Fmx.AstEditor.pas b/Src/AST/Myc.Fmx.AstEditor.pas index 4eddf6a..13fb963 100644 --- a/Src/AST/Myc.Fmx.AstEditor.pas +++ b/Src/AST/Myc.Fmx.AstEditor.pas @@ -17,7 +17,8 @@ uses FMX.Graphics, FMX.StdCtrls, Myc.Ast.Nodes, - Myc.Fmx.AstEditor.Workspace; + Myc.Fmx.AstEditor.Workspace, + Myc.Fmx.AstEditor.Layout; const cNodePadding = 10; @@ -25,9 +26,10 @@ const cTitleBottomPadding = 4; cMinNodeWidth = 10; cMinNodeHeight = 10; + cDragGutterWidth = 20; // Width of the trigger zone for dragging type - TAstViewNode = class; // Forward declaration + TAstViewNode = class; IAstViewNodeHandler = interface function GetAstNode: IAstNode; @@ -36,11 +38,17 @@ type property Node: IAstNode read GetAstNode; end; + IReorderable = interface + ['{9FA7C504-D327-4E00-A5FE-DD2876886212}'] + function CanDrag(Child: TControl): Boolean; + procedure MoveChild(SourceIndex, TargetIndex: Integer); + end; + IAstVisualizer = interface {$region 'private'} function GetExprDepth: Integer; function GetParentControl: TControl; - function GetWorkspace: TAstWorkspace; + function GetWorkspace: TWorkspace; {$endregion} function Clone(ParentControl: TControl; ExprDepth: Integer): IAstVisualizer; @@ -48,34 +56,7 @@ type property ExprDepth: Integer read GetExprDepth; property ParentControl: TControl read GetParentControl; - property Workspace: TAstWorkspace read GetWorkspace; - end; - - TLayoutOrientation = (loVertical, loHorizontal); - TLayoutAlignment = (laCenter, laFlush); - - TAutoFitControl = class(TStyledControl) - private - FUpdatingOwnSize: Boolean; - FNeedRecalcSize: Boolean; - FOrientation: TLayoutOrientation; - FAlignment: TLayoutAlignment; - procedure RecalcOwnSize; - procedure SetOrientation(const Value: TLayoutOrientation); - procedure SetAlignment(const Value: TLayoutAlignment); - protected - procedure ParentContentChanged; override; - procedure PaddingChanged; override; - procedure ChangeChildren; override; - procedure Loaded; override; - procedure DoEndUpdate; override; - public - constructor Create(AOwner: TComponent); override; - - published - property Padding; - property Orientation: TLayoutOrientation read FOrientation write SetOrientation default TLayoutOrientation.loHorizontal; - property Alignment: TLayoutAlignment read FAlignment write SetAlignment default TLayoutAlignment.laCenter; + property Workspace: TWorkspace read GetWorkspace; end; TAstViewNode = class(TAutoFitControl) @@ -106,7 +87,6 @@ type procedure Paint; override; procedure SetupNode; - // Overrides for interaction procedure DoMouseEnter; override; procedure DoMouseLeave; override; procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Single); override; @@ -127,6 +107,7 @@ type property Visualizer: IAstVisualizer read FVisualizer; property Node: IAstNode read GetNode; + property Handler: IAstViewNodeHandler read FHandler; property ErrorMessage: string read FErrorMessage write SetErrorMessage; property TypeInfoText: string read FTypeInfoText write SetTypeInfoText; @@ -184,193 +165,6 @@ implementation uses Myc.Ast; -{ TAutoFitControl } - -constructor TAutoFitControl.Create(AOwner: TComponent); -begin - inherited Create(AOwner); - HitTest := True; - FOrientation := TLayoutOrientation.loHorizontal; - FAlignment := TLayoutAlignment.laCenter; -end; - -procedure TAutoFitControl.SetAlignment(const Value: TLayoutAlignment); -begin - if FAlignment <> Value then - begin - FAlignment := Value; - RecalcOwnSize; - end; -end; - -procedure TAutoFitControl.SetOrientation(const Value: TLayoutOrientation); -begin - if FOrientation <> Value then - begin - FOrientation := Value; - RecalcOwnSize; - end; -end; - -procedure TAutoFitControl.RecalcOwnSize; -var - i: Integer; - child: TControl; - childrenToLayout: TList; - currentX, currentY: Single; - requiredWidth, requiredHeight: Single; - childWidthWithMargins, childHeightWithMargins: Single; - hasVisibleChild: Boolean; -begin - if FUpdatingOwnSize then - exit; - if IsUpdating then - begin - FNeedRecalcSize := True; - exit; - end; - - FUpdatingOwnSize := True; - childrenToLayout := nil; - try - requiredWidth := Padding.Left + Padding.Right; - requiredHeight := Padding.Top + Padding.Bottom; - currentX := Padding.Left; - currentY := Padding.Top; - hasVisibleChild := False; - - childrenToLayout := TList.Create; - for i := 0 to ChildrenCount - 1 do - begin - if Children[i] is TControl then - begin - child := TControl(Children[i]); - if child.Visible and (child.Align = TAlignLayout.None) then - begin - childrenToLayout.Add(child); - hasVisibleChild := True; - end; - end; - end; - - if hasVisibleChild then - begin - if FOrientation = TLayoutOrientation.loVertical then - begin - for child in childrenToLayout do - begin - child.Position.Y := currentY + child.Margins.Top; - currentY := child.Position.Y + child.Height + child.Margins.Bottom; - - childWidthWithMargins := Padding.Left + child.Margins.Left + child.Width + child.Margins.Right + Padding.Right; - requiredWidth := System.Math.Max(requiredWidth, childWidthWithMargins); - end; - requiredHeight := currentY + Padding.Bottom; - - if FAlignment = TLayoutAlignment.laFlush then - begin - for child in childrenToLayout do - begin - child.Position.X := Padding.Left + child.Margins.Left; - end; - end - else - begin - var contentWidth := requiredWidth - Padding.Left - Padding.Right; - for child in childrenToLayout do - begin - var childTotalWidth := child.Width + child.Margins.Left + child.Margins.Right; - var childX := Padding.Left + ((contentWidth - childTotalWidth) / 2) + child.Margins.Left; - child.Position.X := childX; - end; - end; - end - else - begin - for child in childrenToLayout do - begin - child.Position.X := currentX + child.Margins.Left; - currentX := child.Position.X + child.Width + child.Margins.Right; - - childHeightWithMargins := Padding.Top + child.Margins.Top + child.Height + child.Margins.Bottom + Padding.Bottom; - requiredHeight := System.Math.Max(requiredHeight, childHeightWithMargins); - end; - requiredWidth := currentX + Padding.Right; - - if FAlignment = TLayoutAlignment.laFlush then - begin - for child in childrenToLayout do - begin - child.Position.Y := Padding.Top + child.Margins.Top; - end; - end - else - begin - var contentHeight := requiredHeight - Padding.Top - Padding.Bottom; - for child in childrenToLayout do - begin - var childTotalHeight := child.Height + child.Margins.Top + child.Margins.Bottom; - var childY := Padding.Top + ((contentHeight - childTotalHeight) / 2) + child.Margins.Top; - child.Position.Y := childY; - end; - end; - end; - end - else - begin - requiredWidth := Padding.Left + Padding.Right; - requiredHeight := Padding.Top + Padding.Bottom; - end; - - requiredWidth := System.Math.Max(0, requiredWidth); - requiredHeight := System.Math.Max(0, requiredHeight); - - if not SameValue(requiredWidth, Width, TEpsilon.Position) or not SameValue(requiredHeight, Height, TEpsilon.Position) then - begin - FSize.SetSizeWithoutNotification(TSizeF.Create(requiredWidth, requiredHeight)); - HandleSizeChanged; - end; - - finally - childrenToLayout.Free; - FUpdatingOwnSize := False; - end; -end; - -procedure TAutoFitControl.Loaded; -begin - inherited Loaded; - RecalcOwnSize; -end; - -procedure TAutoFitControl.ChangeChildren; -begin - inherited ChangeChildren; - RecalcOwnSize; -end; - -procedure TAutoFitControl.PaddingChanged; -begin - inherited PaddingChanged; - RecalcOwnSize; -end; - -procedure TAutoFitControl.ParentContentChanged; -begin - inherited ParentContentChanged; - RecalcOwnSize; -end; - -procedure TAutoFitControl.DoEndUpdate; -begin - inherited; - if FNeedRecalcSize then - begin - FNeedRecalcSize := False; - RecalcOwnSize; - end; -end; - { TAstViewNode } constructor TAstViewNode.Create(const AVisualizer: IAstVisualizer; const AHandler: IAstViewNodeHandler); @@ -392,7 +186,6 @@ begin Width := cMinNodeWidth; Height := cMinNodeHeight; - // HitTest muss True sein für Hover-Effekte (IsMouseOver) HitTest := True; ClipChildren := True; @@ -419,8 +212,6 @@ end; procedure TAstViewNode.DoMouseEnter; begin inherited; - // Wir müssen neu zeichnen, da sich IsMouseOver geändert hat, - // FMX triggert Paint nicht automatisch bei Hover. Repaint; end; @@ -431,43 +222,43 @@ begin end; procedure TAstViewNode.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Single); -var - pt: TPointF; +const + cHeaderHeight = 30; // Defined height for header drag area begin - inherited; - // Panning-Weiterleitung an den Workspace - if Assigned(FVisualizer.Workspace) then + // Check for Drag Start. + // Condition: Left Click AND we are part of a container (list) + if (Button = TMouseButton.mbLeft) and (Parent is TAutoFitControl) then begin - pt := LocalToAbsolute(TPointF.Create(X, Y)); - pt := FVisualizer.Workspace.AbsoluteToLocal(pt); - FVisualizer.Workspace.ExternalMouseDown(Button, Shift, pt.X, pt.Y); + // Hit-Test: Either Gutter (Left) OR Header area (Top) + if (X < cDragGutterWidth) or (Y < cHeaderHeight) then + begin + if Assigned(FVisualizer.Workspace) then + begin + FVisualizer.Workspace.BeginDragNode(Self); + Exit; + end; + end; end; + + inherited; end; procedure TAstViewNode.MouseMove(Shift: TShiftState; X, Y: Single); -var - pt: TPointF; +const + cHeaderHeight = 30; begin + // Cursor Logic (Hover Feedback) + if (Parent is TAutoFitControl) and ((X < cDragGutterWidth) or (Y < cHeaderHeight)) then + Cursor := crSizeAll + else + Cursor := crDefault; + inherited; - if Assigned(FVisualizer.Workspace) then - begin - pt := LocalToAbsolute(TPointF.Create(X, Y)); - pt := FVisualizer.Workspace.AbsoluteToLocal(pt); - FVisualizer.Workspace.ExternalMouseMove(Shift, pt.X, pt.Y); - end; end; procedure TAstViewNode.MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Single); -var - pt: TPointF; begin inherited; - if Assigned(FVisualizer.Workspace) then - begin - pt := LocalToAbsolute(TPointF.Create(X, Y)); - pt := FVisualizer.Workspace.AbsoluteToLocal(pt); - FVisualizer.Workspace.ExternalMouseUp(Button, Shift, pt.X, pt.Y); - end; end; function TAstViewNode.AddContainer(Parent: TControl; Orientation: TLayoutOrientation; Alignment: TLayoutAlignment): TAutoFitControl; @@ -547,7 +338,6 @@ begin begin FTypeInfoText := Value; UpdateVisualState; - // Type Info usually doesn't change painting, just hint end; end; @@ -585,16 +375,12 @@ begin if Assigned(Node) then begin case Node.Kind of - // Lists and Blocks should generally not be highlighted as a whole on hover - // because they are containers for other selectable items. akBlockExpression, akParameterList, akArgumentList, akExpressionList, akRecordFieldList: shouldIgnoreHover := True; end; end; - // Determine hover state: active only if mouse is over AND it is not a container type isHovering := IsMouseOver and (not shouldIgnoreHover); - // 1. Set base values if FFrameless then begin effBorderColor := FBorderColor; @@ -608,20 +394,13 @@ begin effDash := TStrokeDash.Solid; end; - // 2. Hover state (overrides base, makes frameless nodes visible) if isHovering then begin - // Bright white for strong contrast against dark background effBorderColor := TAlphaColors.White; - - // Make border slightly thicker for a "pop" effect effBorderWidth := Max(2.0, FBorderWidth + 1.0); - - // Always solid line when hovering, even if originally frameless effDash := TStrokeDash.Solid; end; - // 3. Error state (dominates everything) if FErrorMessage <> '' then begin effBorderColor := TAlphaColors.Red; @@ -629,19 +408,13 @@ begin effDash := TStrokeDash.Solid; end; - // --- Drawing --- - - // Fill background Canvas.Fill.Kind := TBrushKind.Solid; Canvas.Fill.Color := FBackgroundColor; if FFrameless and (FErrorMessage = '') and (not isHovering) then begin - // Special case: Inactive, frameless node (e.g., simple constant) - // Draw only background, no border Canvas.FillRect(TRectF.Create(0, 0, Width, Height), 0, 0, [], 1.0); - // Draw border only if explicit width is set (e.g. debugging) if FBorderWidth > 0 then begin Canvas.Stroke.Kind := TBrushKind.Solid; @@ -653,16 +426,12 @@ begin end else begin - // Standard case: Node with border (or hovered frameless node) - rect := TRectF.Create(0, 0, Width, Height); - // Adjust to avoid clipping the border if (effBorderWidth > 0) then rect.Inflate(-effBorderWidth / 2, -effBorderWidth / 2); Canvas.FillRect(rect, FBorderRadius, FBorderRadius, AllCorners, 1.0, TCornerType.Round); - // Draw border if (effBorderWidth > 0) and (effBorderColor <> TAlphaColors.Null) then begin Canvas.Stroke.Kind := TBrushKind.Solid; @@ -672,6 +441,14 @@ begin Canvas.DrawRect(rect, FBorderRadius, FBorderRadius, AllCorners, 1.0, TCornerType.Round); end; end; + + if isHovering and (Parent is TAutoFitControl) then + begin + Canvas.Fill.Color := TAlphaColors.DimGray; + Canvas.FillEllipse(TRectF.Create(4, 6, 8, 10), 1.0); + Canvas.FillEllipse(TRectF.Create(4, 12, 8, 16), 1.0); + Canvas.FillEllipse(TRectF.Create(4, 18, 8, 22), 1.0); + end; end; procedure TAstViewNode.SetBorderColor(const Value: TAlphaColor);