From 18b7b00fc35a60c28a94ce8f28446194710d1e78 Mon Sep 17 00:00:00 2001 From: Creeper Lv Date: Thu, 25 Dec 2025 23:00:26 +1100 Subject: [PATCH] Working on the progrart functions. --- Progrart.Core/Graphics/BaseElement.cs | 24 ++++ Progrart.Core/Graphics/Line.cs | 65 +++++++++++ Progrart.Core/Graphics/ShaderType.cs | 13 +++ Progrart.Core/Graphics/VisualRoot.cs | 51 ++++++--- Progrart.Core/JSExecution/ExecutionEngine.cs | 4 - .../JSExecution/ProgrartConversion.cs | 16 +++ Progrart.Core/JSExecution/ProgrartExecutor.cs | 95 +++++++++++----- .../JSExecution/ProgrartFunctions.cs | 107 ++++++++++++++++-- Progrart.Core/RenderContext.cs | 13 ++- Progrart/Controls/TabSystem/TabHost.axaml.cs | 11 ++ Progrart/Pages/EditorPage.axaml.cs | 1 + Progrart/Pages/EditorProvider.cs | 1 + Progrart/Pages/ExecuteArguments.cs | 4 - Progrart/Pages/ImageViewPage.axaml.cs | 1 + Progrart/Pages/ProgrartEditorPage.axaml.cs | 33 ++++-- Progrart/Views/MainView.axaml | 18 ++- Progrart/Views/MainView.axaml.cs | 39 +++---- 17 files changed, 400 insertions(+), 96 deletions(-) create mode 100644 Progrart.Core/Graphics/BaseElement.cs create mode 100644 Progrart.Core/Graphics/Line.cs create mode 100644 Progrart.Core/Graphics/ShaderType.cs create mode 100644 Progrart.Core/JSExecution/ProgrartConversion.cs diff --git a/Progrart.Core/Graphics/BaseElement.cs b/Progrart.Core/Graphics/BaseElement.cs new file mode 100644 index 0000000..f89b449 --- /dev/null +++ b/Progrart.Core/Graphics/BaseElement.cs @@ -0,0 +1,24 @@ +using Jint; +using Jint.Native; + +namespace Progrart.Core.Graphics +{ + public class BaseElement + { + public List Children = new List(); + public JsObject? __object = null; + public virtual void Add(BaseElement element) + { + Children.Add(element); + } + public virtual void Remove(BaseElement element) + { + Children.Remove(element); + } + public virtual void Render(RenderContext context) + { + } + public virtual void LoadProperties() { } + public virtual void SetupProperties(Engine engine) { } + } +} diff --git a/Progrart.Core/Graphics/Line.cs b/Progrart.Core/Graphics/Line.cs new file mode 100644 index 0000000..81d8a9f --- /dev/null +++ b/Progrart.Core/Graphics/Line.cs @@ -0,0 +1,65 @@ +using Jint; +using Jint.Native; +using Progrart.Core.JSExecution; +using SkiaSharp; + +namespace Progrart.Core.Graphics +{ + public class Line : BaseElement + { + float Size; + float StartX; + float StartY; + float EndX; + float EndY; + float ColorR; + float ColorG; + float ColorB; + float ColorA; + public override void SetupProperties(Engine engine) + { + base.SetupProperties(engine); + if (__object != null) + { + { + JsObject point = new JsObject(engine); + point.Set("x", 0); + point.Set("y", 0); + __object.Set("Start", point); + } + __object.Set("Size", 1); + __object.Set("Color", ProgrartFunctions.color(engine, 1, 1, 1, 1)); + { + JsObject point = new JsObject(engine); + point.Set("x", 0); + point.Set("y", 0); + __object.Set("End", point); + } + + } + + } + public override void LoadProperties() + { + if (__object is not null) + { + Size = (float)__object.Get("Size").AsNumber(); + } + } + public override void Render(RenderContext context) + { + base.Render(context); + context.DrawingCore.canvas.DrawLine( + context.TranslatePoint((float)StartX, (float)StartY), + context.TranslatePoint((float)StartX, (float)StartY), + new SkiaSharp.SKPaint() + { + ColorF = new SkiaSharp.SKColorF(ColorR, ColorG, ColorB, ColorA), + StrokeWidth = Size, + + } + ); + + } + } +} diff --git a/Progrart.Core/Graphics/ShaderType.cs b/Progrart.Core/Graphics/ShaderType.cs new file mode 100644 index 0000000..96c13d0 --- /dev/null +++ b/Progrart.Core/Graphics/ShaderType.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Progrart.Core.Graphics +{ + public enum ShaderType + { + LinearGradient, + RadialGradient, + Picture, + } +} diff --git a/Progrart.Core/Graphics/VisualRoot.cs b/Progrart.Core/Graphics/VisualRoot.cs index 40e9a3d..a8fc46a 100644 --- a/Progrart.Core/Graphics/VisualRoot.cs +++ b/Progrart.Core/Graphics/VisualRoot.cs @@ -1,27 +1,44 @@ -using Jint.Native; -using System; -using System.Collections.Generic; -using System.Text; +using Jint; +using Jint.Native; namespace Progrart.Core.Graphics { - public class BaseElement - { - public JsObject? __object = null; - public virtual void Add(BaseElement element) { } - public virtual void Remove(BaseElement element) { } - public virtual void Render(RenderContext context) - { - } - public virtual void SetProperty(string key, string value) - { - - } - } public class ImageRoot : BaseElement { } public class VisualRoot : BaseElement { + public override void Render(RenderContext context) + { + base.Render(context); + foreach (var item in Children) + { + item.Render(context); + } + } + public override void SetupProperties(Engine engine) + { + base.SetupProperties(engine); + if (__object != null) + { + { + JsObject point = new JsObject(engine); + point.Set("x", 0); + point.Set("y", 0); + __object.Set("translate", point); + } + { + JsObject point = new JsObject(engine); + point.Set("x", 0); + point.Set("y", 0); + __object.Set("scale", point); + } + { + __object.Set("rotation", 0); + } + __object.Set("Width", 1); + __object.Set("Height", 1); + } + } } } diff --git a/Progrart.Core/JSExecution/ExecutionEngine.cs b/Progrart.Core/JSExecution/ExecutionEngine.cs index 0cd8eab..046446f 100644 --- a/Progrart.Core/JSExecution/ExecutionEngine.cs +++ b/Progrart.Core/JSExecution/ExecutionEngine.cs @@ -27,10 +27,6 @@ namespace Progrart.Core.JSExecution { Engine.Evaluate(formSymbol(Symbols)); Engine.Evaluate(content); - if (Engine.GetValue("config").AsObject().TryGetValue("width", out var w)) - { - Trace.WriteLine(w); - } } public void Dispose() diff --git a/Progrart.Core/JSExecution/ProgrartConversion.cs b/Progrart.Core/JSExecution/ProgrartConversion.cs new file mode 100644 index 0000000..b30ef0b --- /dev/null +++ b/Progrart.Core/JSExecution/ProgrartConversion.cs @@ -0,0 +1,16 @@ +using Jint.Native; +using SkiaSharp; +using System; +using System.Collections.Generic; +using System.Text; + +namespace Progrart.Core.JSExecution +{ + public static class ProgrartConversion + { + public static SKShader? ObtainFromJsObject(JsObject jsObject) + { + return null; + } + } +} diff --git a/Progrart.Core/JSExecution/ProgrartExecutor.cs b/Progrart.Core/JSExecution/ProgrartExecutor.cs index 8326b98..6d3226a 100644 --- a/Progrart.Core/JSExecution/ProgrartExecutor.cs +++ b/Progrart.Core/JSExecution/ProgrartExecutor.cs @@ -2,46 +2,69 @@ using Jint.Native; using Jint.Native.Function; using Progrart.Core.Graphics; +using System.Diagnostics; +using System.Text.Json; namespace Progrart.Core.JSExecution { - public class ProgrartExecutor + public class ProgrartExecutor : IDisposable { public ExecutionEngine engine; - public Dictionary ObjectPool = new(); + public Dictionary ObjectPool = new(); public ProgrartExecutor() { engine = new ExecutionEngine(); - engine.Engine.SetValue("visual_root", new Func(() => - { - return ProgrartFunctions.CreateVisualRoot(this); - } - )); - engine.Engine.SetValue("color4", new Func((r, g, b, a) => - { - return ProgrartFunctions.color(this - , r.AsNumber() - , g.AsNumber() - , b.AsNumber() - , a.AsNumber() - ); - } - )); - engine.Engine.SetValue("color3", new Func((r, g, b) => - { - return ProgrartFunctions.color(this - , r.AsNumber() - , g.AsNumber() - , b.AsNumber() - ); - } - )); + SetupCalls(); } - public RenderContext RenderImage(int Scale, string script, Dictionary arguments) + public void SetupCalls() + { + engine.Engine.SetValue("visual_root", visual_root); + Jint.Native.Json.JsonSerializer serializer = new Jint.Native.Json.JsonSerializer(engine.Engine); + engine.Engine.SetValue("log", new Action((v) => + { + if (v is JsObject obj) + { + Trace.WriteLine(serializer.Serialize(obj)); + } + else + Trace.WriteLine(v); + })); + engine.Engine.SetValue("line", line); + engine.Engine.SetValue("color4", color4); + engine.Engine.SetValue("color3", color3); + engine.Engine.SetValue("linear_gradient", linear_gradient); + engine.Engine.SetValue("radial_gradient", radial_gradient); + } + public JsObject color4(JsNumber r, JsNumber g, JsNumber b, JsNumber a) + { + return ProgrartFunctions.color(engine.Engine + , r.AsNumber() + , g.AsNumber() + , b.AsNumber() + , a.AsNumber() + ); + } + public JsObject color3(JsNumber r, JsNumber g, JsNumber b) + { + return ProgrartFunctions.color(engine.Engine + , r.AsNumber() + , g.AsNumber() + , b.AsNumber() + ); + } + public JsObject visual_root() + { + return ProgrartFunctions.CreateVisualRoot(this); + } + public JsObject line() + { + return ProgrartFunctions.CreateLine(this); + } + public RenderContext RenderImage(int Scale, string script, ExecuteArguments arguments) { int width = 1; int height = 1; - foreach (var item in arguments) + foreach (var item in arguments.data) { engine.Engine.SetValue(item.Key, item.Value); } @@ -55,15 +78,25 @@ namespace Progrart.Core.JSExecution } RenderContext renderContext = new RenderContext(width * Scale, width * Scale); ImageRoot imageRoot = new ImageRoot(); + engine.Execute(script); var img = engine.Engine.Call("main"); - imageRoot.Add(ObjectPool[$"{img.Get("id")}"]); + if (ObjectPool[$"{img.Get("id")}"] is BaseElement element) + imageRoot.Add(element); imageRoot.Render(renderContext); return renderContext; } - public int RegisterObject(object obj) + public string RegisterObject(object obj) { - return obj.GetHashCode(); + string v = $"{obj.GetHashCode()}"; + ObjectPool[v] = obj; + return v; + } + public JsObject linear_gradient()=>ProgrartFunctions.linear_gradient(engine.Engine); + public JsObject radial_gradient()=>ProgrartFunctions.radial_gradient(engine.Engine); + public void Dispose() + { + engine.Dispose(); } } } diff --git a/Progrart.Core/JSExecution/ProgrartFunctions.cs b/Progrart.Core/JSExecution/ProgrartFunctions.cs index eeab8cf..a7c9177 100644 --- a/Progrart.Core/JSExecution/ProgrartFunctions.cs +++ b/Progrart.Core/JSExecution/ProgrartFunctions.cs @@ -1,33 +1,115 @@ -using Jint.Native; +using Jint; +using Jint.Native; using Progrart.Core.Graphics; +using SkiaSharp; namespace Progrart.Core.JSExecution { - public static class ProgrartFunctions + public static class ProgrartFunctions { - public static JsObject WrapObject(ProgrartExecutor executor, int Handle) + public static JsObject WrapObject(ProgrartExecutor executor, string Handle) { var obj = new JsObject(executor.engine.Engine); string handle_str = $"{Handle}"; obj.Set("id", handle_str); obj.Set("add", JsValue.FromObject(executor.engine.Engine, new Action((obj) => { - executor.ObjectPool[handle_str].Add(executor.ObjectPool[$"{obj.Get("id")}"]); + if (executor.ObjectPool[handle_str] is BaseElement self) + { + + if (executor.ObjectPool[$"{obj.Get("id")}"] is BaseElement element) + { + self.Add(element); + return; + } + else + throw new Exception($"Object {obj} is not a Progrart Element!"); + } + else + throw new Exception($"Object with id \"{handle_str}\" is not a Progrart Element!"); }))); return obj; } - public static JsObject color(ProgrartExecutor executor, double r, double g, double b, double a) + public static JsObject linear_gradient(Engine engine) { - var obj = new JsObject(executor.engine.Engine); + var obj = new JsObject(engine); + + { + JsObject point = new JsObject(engine); + point.Set("x", 0); + point.Set("y", 0); + obj.Set("Start", point); + } + { + JsObject point = new JsObject(engine); + point.Set("x", 0); + point.Set("y", 0); + obj.Set("End", point); + } + { + obj.Set("Colors", new JsArray(engine, [ + color(engine, 1, 1, 1, 1) , + color(engine, 1, 1, 1, 1) + ] + )); + } + { + obj.Set("Colors", new JsArray(engine, [ + color(engine, 1, 1, 1, 1) , + color(engine, 1, 1, 1, 1) + ] + )); + } + { + obj.Set("Positions", new JsArray(engine, new[] { new JsNumber(0), new JsNumber(1) })); + } + obj.Set("TileMode", $"{SKShaderTileMode.Repeat}"); + obj.Set("Type", $"{ShaderType.LinearGradient}"); + return obj; + } + public static JsObject radial_gradient(Engine engine) + { + var obj = new JsObject(engine); + + { + JsObject point = new JsObject(engine); + point.Set("x", 0); + point.Set("y", 0); + obj.Set("Center", point); + } + { + obj.Set("Colors", new JsArray(engine, [ + color(engine, 1, 1, 1, 1) , + color(engine, 1, 1, 1, 1) + ] + )); + } + { + obj.Set("Colors", new JsArray(engine, [ + color(engine, 1, 1, 1, 1) , + color(engine, 1, 1, 1, 1) + ] + )); + } + { + obj.Set("Positions", new JsArray(engine, new[] { new JsNumber(0), new JsNumber(1) })); + } + obj.Set("TileMode", $"{SKShaderTileMode.Repeat}"); + obj.Set("Type", $"{ShaderType.RadialGradient}"); + return obj; + } + public static JsObject color(Engine engine, double r, double g, double b, double a) + { + var obj = new JsObject(engine); obj.Set("r", r); obj.Set("g", g); obj.Set("b", b); obj.Set("a", a); return obj; } - public static JsObject color(ProgrartExecutor executor, double r, double g, double b) + public static JsObject color(Engine engine, double r, double g, double b) { - var obj = new JsObject(executor.engine.Engine); + var obj = new JsObject(engine); obj.Set("r", r); obj.Set("g", g); obj.Set("b", b); @@ -39,6 +121,15 @@ namespace Progrart.Core.JSExecution VisualRoot root = new(); var obj = WrapObject(executor, executor.RegisterObject(root)); root.__object = obj; + root.SetupProperties(executor.engine.Engine); + return obj; + } + public static JsObject CreateLine(ProgrartExecutor executor) + { + Line root = new(); + var obj = WrapObject(executor, executor.RegisterObject(root)); + root.__object = obj; + root.SetupProperties(executor.engine.Engine); return obj; } } diff --git a/Progrart.Core/RenderContext.cs b/Progrart.Core/RenderContext.cs index 6c7d5e8..692910e 100644 --- a/Progrart.Core/RenderContext.cs +++ b/Progrart.Core/RenderContext.cs @@ -11,7 +11,10 @@ namespace Progrart.Core { this.DrawingCore = core; } - + public SKPoint TranslatePoint(float x, float y) + { + return new SKPoint(x * DrawingCore.Width, y * DrawingCore.Height); + } public RenderContext(int W, int H) { DrawingCore = new PrimitiveDrawingCore(W, H); @@ -22,9 +25,13 @@ namespace Progrart.Core internal bool isDisposed = false; SKSurface surface; SKImageInfo info; + public readonly int Width; + public readonly int Height; public SKCanvas canvas { get; } public PrimitiveDrawingCore(int W, int H) { + Width = W; + Height = H; info = new SKImageInfo(W, H); surface = SKSurface.Create(info); canvas = surface.Canvas; @@ -38,6 +45,10 @@ namespace Progrart.Core } } + public class ExecuteArguments + { + public Dictionary data = new Dictionary(); + } [Serializable] public class RenderConfig { diff --git a/Progrart/Controls/TabSystem/TabHost.axaml.cs b/Progrart/Controls/TabSystem/TabHost.axaml.cs index 5ceac6a..e46dfdc 100644 --- a/Progrart/Controls/TabSystem/TabHost.axaml.cs +++ b/Progrart/Controls/TabSystem/TabHost.axaml.cs @@ -10,6 +10,17 @@ public partial class TabHost : UserControl { InitializeComponent(); } + public ITabPage? GetCurrentPage() + { + foreach (var item in PageContainer.Children) + { + if (item.IsVisible) + { + if (item is ITabPage page) return page; + } + } + return null; + } public void AddPage(ITabPage page) { TabButton button = new TabButton(page, this); diff --git a/Progrart/Pages/EditorPage.axaml.cs b/Progrart/Pages/EditorPage.axaml.cs index 6995030..9583e49 100644 --- a/Progrart/Pages/EditorPage.axaml.cs +++ b/Progrart/Pages/EditorPage.axaml.cs @@ -6,6 +6,7 @@ using Avalonia.Threading; using AvaloniaEdit; using AvaloniaEdit.TextMate; using Progrart.Controls.TabSystem; +using Progrart.Core; using Progrart.Icons; using System.IO; using System.Threading.Tasks; diff --git a/Progrart/Pages/EditorProvider.cs b/Progrart/Pages/EditorProvider.cs index 8cf759c..7f3edf8 100644 --- a/Progrart/Pages/EditorProvider.cs +++ b/Progrart/Pages/EditorProvider.cs @@ -1,6 +1,7 @@ using Avalonia.Controls; using Avalonia.Platform.Storage; using Progrart.Controls.TabSystem; +using Progrart.Core; using System; using System.Collections.Generic; using System.Diagnostics; diff --git a/Progrart/Pages/ExecuteArguments.cs b/Progrart/Pages/ExecuteArguments.cs index e25faf8..74c4477 100644 --- a/Progrart/Pages/ExecuteArguments.cs +++ b/Progrart/Pages/ExecuteArguments.cs @@ -2,8 +2,4 @@ namespace Progrart.Pages { - public class ExecuteArguments - { - public Dictionary data = new Dictionary(); - } } \ No newline at end of file diff --git a/Progrart/Pages/ImageViewPage.axaml.cs b/Progrart/Pages/ImageViewPage.axaml.cs index 1ed8818..a893ccf 100644 --- a/Progrart/Pages/ImageViewPage.axaml.cs +++ b/Progrart/Pages/ImageViewPage.axaml.cs @@ -5,6 +5,7 @@ using Avalonia.Media.Imaging; using Avalonia.Platform.Storage; using Avalonia.Threading; using Progrart.Controls.TabSystem; +using Progrart.Core; using System.Threading.Tasks; namespace Progrart.Pages; diff --git a/Progrart/Pages/ProgrartEditorPage.axaml.cs b/Progrart/Pages/ProgrartEditorPage.axaml.cs index ba41212..c2969a3 100644 --- a/Progrart/Pages/ProgrartEditorPage.axaml.cs +++ b/Progrart/Pages/ProgrartEditorPage.axaml.cs @@ -4,20 +4,23 @@ using Avalonia.Markup.Xaml; using Avalonia.Platform.Storage; using Avalonia.Threading; using Progrart.Controls.TabSystem; +using Progrart.Core; +using Progrart.Core.JSExecution; using Progrart.Pages; +using System.Diagnostics; using System.IO; using System.Threading.Tasks; namespace Progrart; -public partial class ProgrartEditorPage : UserControl, ITabPage,IEditorPage +public partial class ProgrartEditorPage : UserControl, ITabPage, IEditorPage { IStorageFile? file = null; TabButton? btn = null; public ProgrartEditorPage() - { - InitializeComponent(); - } + { + InitializeComponent(); + } public void BindButton(TabButton button) { @@ -32,13 +35,23 @@ public partial class ProgrartEditorPage : UserControl, ITabPage,IEditorPage } public void Execute(ExecuteArguments? args = null) - { - } + { + using ProgrartExecutor executor = new ProgrartExecutor(); + try + { + executor.RenderImage(100, CodeEditor.Text, new ExecuteArguments()); - public bool IsModified() - { - return false; - } + } + catch (System.Exception e) + { + Trace.WriteLine(e); + } + } + + public bool IsModified() + { + return false; + } public void LoadDocument(IStorageFile file) { diff --git a/Progrart/Views/MainView.axaml b/Progrart/Views/MainView.axaml index b2f2cb2..efeb358 100644 --- a/Progrart/Views/MainView.axaml +++ b/Progrart/Views/MainView.axaml @@ -168,10 +168,24 @@ - Output + + + + + + Output + + + + + - + diff --git a/Progrart/Views/MainView.axaml.cs b/Progrart/Views/MainView.axaml.cs index 9494dc9..865aa19 100644 --- a/Progrart/Views/MainView.axaml.cs +++ b/Progrart/Views/MainView.axaml.cs @@ -11,26 +11,12 @@ namespace Progrart.Views; public partial class MainView : UserControl { - ExecutionEngine engine; static MainView? Instance; public MainView() { Instance = this; InitializeComponent(); - engine = new ExecutionEngine(); - //engine.Engine.SetValue("log", new Action((s) => { Output.Text += $"{s}\n"; })); - RunButton.Click += (_, _) => - { - try - { - //engine.Execute(CodePane.Text); - } - catch (Exception e) - { - WriteLine(e.Message); - } - }; - //Trace.Listeners.Add(new ConsoleLogger()); + Trace.Listeners.Add(new ConsoleLogger()); EditorProvider.setHost(MainTabHost); BottomPanelToggle.IsCheckedChanged += (a, b) => { @@ -89,11 +75,24 @@ public partial class MainView : UserControl LeftPanelToggle.IsChecked = false; }; LeftPanelToggle.IsChecked = true; + RunButton.Click += (_, _) => + { + if (MainTabHost.GetCurrentPage() is IEditorPage editor) + { + editor.Execute(null); + } + }; } + + private void OutputClear_Click(object? sender, Avalonia.Interactivity.RoutedEventArgs e) + { + Output.Text = ""; + } + public void Write(string message) { - //Dispatcher.UIThread.Invoke(() => - //Output.Text += message); + Dispatcher.UIThread.Invoke(() => + Output.Text += message); try { Output.Text += message; @@ -104,10 +103,12 @@ public partial class MainView : UserControl } public void WriteLine(string message) { - //Dispatcher.UIThread.Invoke(() =>); - try + Dispatcher.UIThread.Invoke(() => { Output.Text += $"{message}\n"; + }); + try + { } catch (Exception) {