diff --git a/Directory.Packages.props b/Directory.Packages.props index 351377d..9b00e79 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -22,6 +22,7 @@ + diff --git a/Progrart.Core/Progrart.Core.csproj b/Progrart.Core/Progrart.Core.csproj index d7dbea6..242773c 100644 --- a/Progrart.Core/Progrart.Core.csproj +++ b/Progrart.Core/Progrart.Core.csproj @@ -8,6 +8,7 @@ + diff --git a/Progrart.Core/ProjectSystem/Builder.cs b/Progrart.Core/ProjectSystem/Builder.cs new file mode 100644 index 0000000..a1f7d13 --- /dev/null +++ b/Progrart.Core/ProjectSystem/Builder.cs @@ -0,0 +1,58 @@ +using Newtonsoft.Json; +using Progrart.Core.JSExecution; + +namespace Progrart.Core.ProjectSystem +{ + public class Builder + { + public Project project; + public string basePath; + public Action? OnProgressUpdate; + public Action? OnCompleted; + public Builder(StreamReader reader, string basePath) + { + var project = JsonConvert.DeserializeObject(reader.ReadToEnd()); + if (project is null) throw new JsonSerializationException(); + this.project = project; + this.basePath = basePath; + } + public Builder(Project project, string basePath) + { + this.project = project; + this.basePath = basePath; + } + public void Execute(BuildConfiguration config, BuildItem item) + { + FileInfo src = new FileInfo(Path.Combine(basePath, item.Source)); + FileInfo tgt = new FileInfo(Path.Combine(basePath, project.OutputDir, item.Target ?? item.Source + ".png")); + var args = project.Arguments.Clone(); + args.MergeFrom(config.Arguments); + args.MergeFrom(item.Arguments); + ProgrartExecutor executor = new ProgrartExecutor(); + using var stream = src.OpenRead(); + using var reader = new StreamReader(stream); + var img = executor.RenderImage(item.Size, reader.ReadToEnd(), args); + using var img_stream = tgt.OpenWrite(); + img.DrawingCore.ToData().SaveTo(img_stream); + img_stream.Flush(); + } + public void Build(string targetConfig) + { + foreach (var config in project.Configurations) + { + if (config.Name == targetConfig) + { + int index = 0; + foreach (var item in config.Items) + { + Execute(config, item); + index++; + OnProgressUpdate?.Invoke(config.Items.Count, index); + } + OnCompleted?.Invoke(); + return; + } + } + } + } +} diff --git a/Progrart.Core/ProjectSystem/Project.cs b/Progrart.Core/ProjectSystem/Project.cs index 4ca6034..e8f2e56 100644 --- a/Progrart.Core/ProjectSystem/Project.cs +++ b/Progrart.Core/ProjectSystem/Project.cs @@ -7,18 +7,24 @@ namespace Progrart.Core.ProjectSystem [Serializable] public class Project { + public string OutputDir = "output"; public List Configurations = new List(); + public ExecuteArguments Arguments = new ExecuteArguments(); } [Serializable] public class BuildConfiguration { public string? Name; + public string? OutputDir; public List Items = new List(); + public ExecuteArguments Arguments = new ExecuteArguments(); } [Serializable] public class BuildItem { - public string? Source; + public string Source = ""; public string? Target; + public int Size; + public ExecuteArguments Arguments = new ExecuteArguments(); } } diff --git a/Progrart.Core/RenderContext.cs b/Progrart.Core/RenderContext.cs index fb17f07..861f2ff 100644 --- a/Progrart.Core/RenderContext.cs +++ b/Progrart.Core/RenderContext.cs @@ -24,7 +24,7 @@ namespace Progrart.Core } public float TranslateSize(float s) { - return (float)(s * Math.Sqrt(DrawingCore.Width * DrawingCore.Width + DrawingCore.Height * DrawingCore.Height)/ Math.Sqrt(LogicalH * LogicalH + LogicalW * LogicalW)); + return (float)(s * Math.Sqrt(DrawingCore.Width * DrawingCore.Width + DrawingCore.Height * DrawingCore.Height) / Math.Sqrt(LogicalH * LogicalH + LogicalW * LogicalW)); } public RenderContext(int W, int H) { @@ -61,10 +61,27 @@ namespace Progrart.Core surface.Dispose(); } } - + [Serializable] public class ExecuteArguments { public Dictionary data = new Dictionary(); + public ExecuteArguments Clone() + { + ExecuteArguments args = new ExecuteArguments(); + foreach (var item in data) + { + args.data.Add(item.Key, item.Value); + } + return args; + } + public void MergeFrom(ExecuteArguments args) + { + + foreach (var item in args.data) + { + args.data.Add(item.Key, item.Value); + } + } } [Serializable] public class RenderConfig diff --git a/Progrart/Assets/Styles/JavaScript.xml b/Progrart/Assets/Styles/JavaScript.xml new file mode 100644 index 0000000..20fc655 --- /dev/null +++ b/Progrart/Assets/Styles/JavaScript.xml @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + break + continue + delete + else + for + function + if + in + new + return + this + typeof + var + void + while + with + abstract + boolean + byte + case + catch + char + class + const + debugger + default + do + double + enum + export + extends + final + finally + float + goto + implements + import + instanceof + int + interface + long + native + package + private + protected + public + short + static + super + switch + synchronized + throw + throws + transient + try + volatile + + + Array + Boolean + Date + Function + Global + Math + Number + Object + RegExp + String + + + false + null + true + NaN + Infinity + + + eval + parseInt + parseFloat + escape + unescape + isNaN + isFinite + + + // + + + /\* + \*/ + + + (?<!([})\]\w]+\s*))/ + / + + + " + " + + + + + + ' + ' + + + + + \b0[xX][0-9a-fA-F]+|(\b\d+(\.[0-9]+)?|\.[0-9]+)([eE][+-]?[0-9]+)? + + \ No newline at end of file diff --git a/Progrart/Controls/BaseEditor.axaml b/Progrart/Controls/BaseEditor.axaml index 2e24770..2bb4e42 100644 --- a/Progrart/Controls/BaseEditor.axaml +++ b/Progrart/Controls/BaseEditor.axaml @@ -7,12 +7,14 @@ x:Class="Progrart.Controls.BaseEditor"> + FontFamily="Sarasa Mono Slab CL,Cascadia Code,Roboto Mono,Consolas,Menlo,Monospace"> + + diff --git a/Progrart/Controls/BaseEditor.axaml.cs b/Progrart/Controls/BaseEditor.axaml.cs index 9001826..505f734 100644 --- a/Progrart/Controls/BaseEditor.axaml.cs +++ b/Progrart/Controls/BaseEditor.axaml.cs @@ -2,76 +2,99 @@ using Avalonia; using Avalonia.Controls; using Avalonia.Input; using Avalonia.Markup.Xaml; +using Avalonia.Platform; using AvaloniaEdit; +using AvaloniaEdit.Highlighting; +using AvaloniaEdit.Highlighting.Xshd; using AvaloniaEdit.TextMate; using Progrart.Commands; using System; +using System.IO; using System.Threading.Tasks; using System.Windows.Input; +using System.Xml; using TextMateSharp.Grammars; namespace Progrart.Controls; public partial class BaseEditor : UserControl { - RegistryOptions? _registryOptions; - TextMate.Installation? _textMateInstallation; - public string Text - { - get => CodeEditBox.Text; - set => CodeEditBox.Text = value; - } - public Func? onSaveCmd; - public BaseEditor() - { - InitializeComponent(); + RegistryOptions? _registryOptions; + TextMate.Installation? _textMateInstallation; + public string Text + { + get => CodeEditBox.Text; + set => CodeEditBox.Text = value; + } + public Func? onSaveCmd; + public BaseEditor() + { + InitializeComponent(); + var uri = new Uri("avares://Progrart/Assets/Styles/JavaScript.xml"); + if (AssetLoader.Exists(uri)) + { + using (Stream stream = AssetLoader.Open(uri)) + { + using (XmlReader reader = XmlReader.Create(stream)) + { + var xshd = HighlightingLoader.LoadXshd(reader); + CodeEditBox.SyntaxHighlighting = HighlightingLoader.Load(xshd, HighlightingManager.Instance); + } + } + } if (!OperatingSystem.IsBrowser()) - { - var _textEditor = CodeEditBox; - _registryOptions = new RegistryOptions(ThemeName.DarkPlus); - _textMateInstallation = _textEditor.InstallTextMate(_registryOptions); - _textMateInstallation.SetGrammar(_registryOptions.GetScopeByLanguageId(_registryOptions.GetLanguageByExtension(".js").Id)); - } - var saveBinding = new KeyBinding - { - Gesture = new KeyGesture(Key.S, KeyModifiers.Control), - Command = new GenericCommand() { onExecute = (_) => Task.Run(Save) } - }; + { + var _textEditor = CodeEditBox; + _registryOptions = new RegistryOptions(ThemeName.DarkPlus); + _textMateInstallation = _textEditor.InstallTextMate(_registryOptions); + _textMateInstallation.SetGrammar(_registryOptions.GetScopeByLanguageId(_registryOptions.GetLanguageByExtension(".js").Id)); + } + var saveBinding = new KeyBinding + { + Gesture = new KeyGesture(Key.S, KeyModifiers.Control), + Command = new GenericCommand() { onExecute = (_) => Task.Run(Save) } + }; - CodeEditBox.KeyBindings.Add(saveBinding); - } - async Task Save() - { - if (onSaveCmd is not null) - await onSaveCmd.Invoke(); - } - public void SetGrammerByExtension(string extension_name) - { - if (OperatingSystem.IsBrowser()) - { - return; - } - _textMateInstallation?.SetGrammar( - _registryOptions?.GetScopeByLanguageId( - _registryOptions.GetLanguageByExtension(extension_name).Id - ) - ); + CodeEditBox.KeyBindings.Add(saveBinding); + } + async Task Save() + { + if (onSaveCmd is not null) + await onSaveCmd.Invoke(); + } + public void SetGrammerByExtension(string extension_name) + { + if (OperatingSystem.IsBrowser()) + { + return; + } + _textMateInstallation?.SetGrammar( + _registryOptions?.GetScopeByLanguageId( + _registryOptions.GetLanguageByExtension(extension_name).Id + ) + ); - } + } - private void Copy_Click(object? sender, Avalonia.Interactivity.RoutedEventArgs e) - { - CodeEditBox.Copy(); - } + private void Copy_Click(object? sender, Avalonia.Interactivity.RoutedEventArgs e) + { + CodeEditBox.Copy(); + } - private void Paste_Click(object? sender, Avalonia.Interactivity.RoutedEventArgs e) - { - CodeEditBox.Paste(); - } + private void Paste_Click(object? sender, Avalonia.Interactivity.RoutedEventArgs e) + { + CodeEditBox.Paste(); + } + + private void Cut_Click(object? sender, Avalonia.Interactivity.RoutedEventArgs e) + { + CodeEditBox.Cut(); + } + + private void Find_Click(object? sender, Avalonia.Interactivity.RoutedEventArgs e) + { + CodeEditBox.SearchPanel.Open(); - private void Cut_Click(object? sender, Avalonia.Interactivity.RoutedEventArgs e) - { - CodeEditBox.Cut(); } } \ No newline at end of file diff --git a/Progrart/Pages/ExecuteArguments.cs b/Progrart/Pages/ExecuteArguments.cs deleted file mode 100644 index 74c4477..0000000 --- a/Progrart/Pages/ExecuteArguments.cs +++ /dev/null @@ -1,5 +0,0 @@ -using System.Collections.Generic; - -namespace Progrart.Pages -{ -} \ No newline at end of file diff --git a/Progrart/Pages/ProgrartEditorPage.axaml.cs b/Progrart/Pages/ProgrartEditorPage.axaml.cs index fd47f92..bab9483 100644 --- a/Progrart/Pages/ProgrartEditorPage.axaml.cs +++ b/Progrart/Pages/ProgrartEditorPage.axaml.cs @@ -19,6 +19,7 @@ public partial class ProgrartEditorPage : UserControl, ITabPage, IEditorPage { IStorageFile? file = null; TabButton? btn = null; + Bitmap? image; public ProgrartEditorPage() { InitializeComponent(); @@ -52,16 +53,19 @@ public partial class ProgrartEditorPage : UserControl, ITabPage, IEditorPage } var result = executor.RenderImage(1024, CodeEditor.Text, args ?? new ExecuteArguments()); var data = result.DrawingCore.ToData(); - var imgFile = Path.GetTempFileName(); - Trace.WriteLine($"Generated to:{imgFile}"); - using (var stream = File.OpenWrite(imgFile)) - { - data.SaveTo(stream); - stream.Flush(); - stream.Close(); - } - Bitmap image = new Bitmap(imgFile); + using MemoryStream stream = new MemoryStream(); + + data.SaveTo(stream); + stream.Flush(); + + stream.Position = 0; + Bitmap image = new Bitmap(stream); PreviewImage.SetImage(image); + if (this.image != null) + { + this.image.Dispose(); + } + this.image = image; } catch (System.Exception e) { @@ -91,21 +95,17 @@ public partial class ProgrartEditorPage : UserControl, ITabPage, IEditorPage { CodeEditor.SetGrammerByExtension(".js"); } + Trace.WriteLine($"File:{file.TryGetLocalPath() ?? "null"}"); Task.Run(async () => { using var stream = await file.OpenReadAsync(); using StreamReader sr = new StreamReader(stream); - var text = sr.ReadToEnd(); - if (OperatingSystem.IsBrowser()) + var text = await sr.ReadToEndAsync(); + Dispatcher.UIThread.Invoke(() => { - CodeEditor.Text = text; - } - else - Dispatcher.UIThread.Invoke(() => - { - CodeEditor.Text = text; - }); + + }); }); } diff --git a/Progrart/Progrart.csproj b/Progrart/Progrart.csproj index 6882424..4691370 100644 --- a/Progrart/Progrart.csproj +++ b/Progrart/Progrart.csproj @@ -9,6 +9,10 @@ + + + + diff --git a/Progrart/Views/MainView.axaml b/Progrart/Views/MainView.axaml index 64609fa..c7b567c 100644 --- a/Progrart/Views/MainView.axaml +++ b/Progrart/Views/MainView.axaml @@ -44,6 +44,7 @@ + diff --git a/Progrart/Views/MainView.axaml.cs b/Progrart/Views/MainView.axaml.cs index b8e6516..48b7f94 100644 --- a/Progrart/Views/MainView.axaml.cs +++ b/Progrart/Views/MainView.axaml.cs @@ -22,16 +22,17 @@ public partial class MainView : UserControl InitializeComponent(); Trace.Listeners.Add(new ConsoleLogger()); EditorProvider.setHost(MainTabHost); + MenuButton.Focus(); this.KeyBindings.Add(new Avalonia.Input.KeyBinding() { Gesture = new Avalonia.Input.KeyGesture(Avalonia.Input.Key.Space, - Avalonia.Input.KeyModifiers.Shift | Avalonia.Input.KeyModifiers.Control), + Avalonia.Input.KeyModifiers.Control | Avalonia.Input.KeyModifiers.Shift), Command = new GenericCommand() { Checker = (_) => true, onExecute = (_) => { - MenuButton.ContextMenu?.Open(); + MenuButton.Flyout?.ShowAt(MenuButton); } } });