Focus & cursor movement in UI

This commit is contained in:
Michael Schimmel
2025-12-01 13:19:07 +01:00
parent 68a97e6985
commit 656375de99
10 changed files with 1468 additions and 867 deletions
+30 -40
View File
@@ -44,9 +44,7 @@ uses
Myc.Ast.RTL,
Myc.Ast.Compiler.Macros,
// Editor Units
Myc.Fmx.AstEditor,
Myc.Fmx.AstEditor.Workspace,
Myc.Fmx.AstEditor.Controller; // Controller integration
Myc.Fmx.AstEditor; // Die neue Komponente (ersetzt Controller und Workspace-Access)
type
// A test record
@@ -93,7 +91,6 @@ type
procedure ClearButtonClick(Sender: TObject);
procedure CompilerStageBoxChange(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure CreateTriggerExampleButtonClick(Sender: TObject);
procedure DebugBoxChange(Sender: TObject);
procedure DoTrigger2ButtonClick(Sender: TObject);
@@ -119,17 +116,16 @@ type
FCurrUnboundAst: IAstNode;
FCurrExec: TCompiledFunction;
FEnvironment: TAstEnvironment;
FWorkspace: TWorkspace; // Changed to TWorkspace
FController: TAstEditorController; // The UI Controller
FAstEditor: TAstEditor; // Die Komponente (Facade)
FScriptUpdate: Boolean;
FTriggerTest: TAstEnvironment;
procedure WorkspaceMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single);
procedure AstEditorMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single);
// Helper function to encapsulate the Compile -> Evaluate pattern
function ExecuteAst(const ANode: IAstNode): TDataValue;
procedure UpdateScript;
procedure ShowVizualization(X, Y: Single);
procedure ShowVizualization;
procedure PrintScript(const Node: IAstNode);
public
{ Public declarations }
@@ -158,19 +154,20 @@ begin
// 1. Initialize Environment
FEnvironment := TAstEnvironment.Construct(TAst.CreateScope(nil));
// 2. Initialize Workspace
// TWorkspace is now a simple viewport control
FWorkspace := TWorkspace.Create(Panel2);
FWorkspace.Parent := Panel2;
FWorkspace.Align := TAlignLayout.Client;
FWorkspace.ClipChildren := true;
FWorkspace.OnMouseDown := WorkspaceMouseDown;
// 2. Initialize AST Editor Component
// This replaces the manual Workspace + Controller setup.
// The Editor encapsulates logic for Navigation, Zoom, Drag&Drop, Undo/Redo.
FAstEditor := TAstEditor.Create(Self);
FAstEditor.Parent := Panel2;
FAstEditor.Align := TAlignLayout.Client;
// 3. Initialize Controller (connects Env and Workspace)
// The Controller will manage the nodes inside FWorkspace.World
FController := TAstEditorController.Create(FEnvironment, FWorkspace);
// Wire up events exposed by the component
FAstEditor.OnMouseDown := AstEditorMouseDown;
// 4. Register the SMA factory into the environment
// Initialize the logic backend of the editor
FAstEditor.Init(FEnvironment);
// 3. Register the SMA factory into the environment
var RegFunc :=
procedure(const Scope: IExecutionScope)
var
@@ -286,19 +283,13 @@ begin
ClearButtonClick(Self);
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
FController.Free;
end;
procedure TForm1.ShowVizualization(X, Y: Single);
procedure TForm1.ShowVizualization;
begin
if FCurrUnboundAst = nil then
exit;
// Use the Controller to build, validate and show the UI
// The controller internally clears FWorkspace.World and adds nodes there.
FController.SetRoot(FCurrUnboundAst);
// Use the Editor Component to build, validate and show the UI
FAstEditor.SetRoot(FCurrUnboundAst);
end;
// Simplified ExecuteAst using TEnvironment and handling errors gracefully
@@ -422,14 +413,13 @@ end;
procedure TForm1.ClearButtonClick(Sender: TObject);
begin
// Clear content of world (not workspace itself, as it has the root layer)
FWorkspace.World.DeleteChildren;
FWorkspace.World.Repaint;
// Clear content of component
FAstEditor.SetRoot(nil);
end;
procedure TForm1.CompilerStageBoxChange(Sender: TObject);
begin
ShowVizualization(14, 14);
ShowVizualization;
end;
procedure TForm1.CreateTriggerExampleButtonClick(Sender: TObject);
@@ -731,8 +721,8 @@ begin
var result := ExecuteAst(FCurrUnboundAst);
Memo1.Lines.Add(Format('Script executed. Final result: %s', [result.ToString]));
finally
// Trigger visualization update via Controller (inside ShowVizualization)
ShowVizualization(14, 14);
// Trigger visualization update via Component
ShowVizualization;
end;
except
on E: Exception do
@@ -890,15 +880,15 @@ procedure TForm1.UpdateScript;
begin
PrintScript(FCurrUnboundAst);
// Clear and redraw via Controller
FController.SetRoot(FCurrUnboundAst);
// Clear and redraw via Component
FAstEditor.SetRoot(FCurrUnboundAst);
end;
procedure TForm1.WorkspaceMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single);
procedure TForm1.AstEditorMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single);
begin
if Button <> TMouseButton.mbMiddle then
exit;
ShowVizualization(X, Y);
// Nur zur Demo: Wir könnten hier klicken, um etwas im Memo zu loggen
if Button = TMouseButton.mbMiddle then
ShowVizualization;
end;
procedure TForm1.SaveUserLibButtonClick(Sender: TObject);