Working on the project editor.

Implemented a very basic version of command line tool.
This commit is contained in:
Creeper Lv
2026-01-11 03:54:14 +11:00
parent 609e51d375
commit 1bcaff76b2
19 changed files with 452 additions and 5 deletions

30
.dockerignore Normal file
View File

@@ -0,0 +1,30 @@
**/.classpath
**/.dockerignore
**/.env
**/.git
**/.gitignore
**/.project
**/.settings
**/.toolstarget
**/.vs
**/.vscode
**/*.*proj.user
**/*.dbmdl
**/*.jfm
**/azds.yaml
**/bin
**/charts
**/docker-compose*
**/Dockerfile*
**/node_modules
**/npm-debug.log
**/obj
**/secrets.dev.yaml
**/values.dev.yaml
LICENSE
README.md
!**/.gitignore
!.git/HEAD
!.git/config
!.git/packed-refs
!.git/refs/heads/**

View File

@@ -23,6 +23,7 @@
<PackageVersion Include="Jint" Version="4.4.2" /> <PackageVersion Include="Jint" Version="4.4.2" />
<PackageVersion Include="Microsoft.Maui.Graphics" Version="10.0.11" /> <PackageVersion Include="Microsoft.Maui.Graphics" Version="10.0.11" />
<PackageVersion Include="Microsoft.Maui.Graphics.Skia" Version="10.0.11" /> <PackageVersion Include="Microsoft.Maui.Graphics.Skia" Version="10.0.11" />
<PackageVersion Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.23.0" />
<PackageVersion Include="Newtonsoft.Json" Version="13.0.4" /> <PackageVersion Include="Newtonsoft.Json" Version="13.0.4" />
<PackageVersion Include="PanAndZoom" Version="11.3.6" /> <PackageVersion Include="PanAndZoom" Version="11.3.6" />
<PackageVersion Include="SkiaSharp" Version="3.116.1" /> <PackageVersion Include="SkiaSharp" Version="3.116.1" />

47
Progrart.Cmd/Dockerfile Normal file
View File

@@ -0,0 +1,47 @@
# See https://aka.ms/customizecontainer to learn how to customize your debug container and how Visual Studio uses this Dockerfile to build your images for faster debugging.
# These ARGs allow for swapping out the base used to make the final image when debugging from VS
ARG LAUNCHING_FROM_VS
# This sets the base image for final, but only if LAUNCHING_FROM_VS has been defined
ARG FINAL_BASE_IMAGE=${LAUNCHING_FROM_VS:+aotdebug}
# This stage is used when running from VS in fast mode (Default for Debug configuration)
FROM mcr.microsoft.com/dotnet/runtime:10.0 AS base
USER $APP_UID
WORKDIR /app
# This stage is used to build the service project
FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build
# Install clang/zlib1g-dev dependencies for publishing to native
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
clang zlib1g-dev
ARG BUILD_CONFIGURATION=Release
WORKDIR /src
COPY ["Directory.Packages.props", "."]
COPY ["Progrart.Cmd/Progrart.Cmd.csproj", "Progrart.Cmd/"]
RUN dotnet restore "./Progrart.Cmd/Progrart.Cmd.csproj"
COPY . .
WORKDIR "/src/Progrart.Cmd"
RUN dotnet build "./Progrart.Cmd.csproj" -c $BUILD_CONFIGURATION -o /app/build
# This stage is used to publish the service project to be copied to the final stage
FROM build AS publish
ARG BUILD_CONFIGURATION=Release
RUN dotnet publish "./Progrart.Cmd.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=true
# This stage is used as the base for the final stage when launching from VS to support debugging in regular mode (Default when not using the Debug configuration)
FROM base AS aotdebug
USER root
# Install GDB to support native debugging
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
gdb
USER app
# This stage is used in production or when running from VS in regular mode (Default when not using the Debug configuration)
FROM ${FINAL_BASE_IMAGE:-mcr.microsoft.com/dotnet/runtime-deps:10.0} AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["./Progrart.Cmd"]

67
Progrart.Cmd/Program.cs Normal file
View File

@@ -0,0 +1,67 @@
using Progrart.Core.ProjectSystem;
using Progrart.Core.Storage;
namespace Progrart.Cmd
{
internal class Program
{
static void Main(string[] args)
{
string? project_file = null;
string? configuration = null;
for (int i = 0; i < args.Length; i++)
{
string? item = args[i];
switch (item)
{
case "-c":
case "--config":
case "--configuration":
{
i++;
item = args[i];
configuration = item;
}
break;
default:
{
if (File.Exists(item))
{
project_file = item;
}
}
break;
}
}
if (project_file != null)
if (configuration != null)
{
FileInfo fi = new FileInfo(project_file);
if (fi.Directory is DirectoryInfo di)
{
using var fs = fi.OpenRead();
using var sr = new StreamReader(fs);
ClassicStorageProvider provider = new ClassicStorageProvider(di);
Builder builder = new Builder(sr, provider);
builder.OnProgressUpdate = (v, m) =>
{
Console.WriteLine($"{v}/{m}");
};
builder.OnCompleted = () =>
{
Environment.Exit(0);
};
Task.Run(async () =>
{
await builder.Build(configuration);
});
while (true)
{
Thread.Sleep(1000);
}
}
}
}
}
}

View File

@@ -0,0 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<PublishAot>true</PublishAot>
<InvariantGlobalization>true</InvariantGlobalization>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Progrart.Core\Progrart.Core.csproj" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,10 @@
{
"profiles": {
"Progrart.Cmd": {
"commandName": "Project"
},
"Container (Dockerfile)": {
"commandName": "Docker"
}
}
}

View File

@@ -16,10 +16,12 @@ namespace Progrart.Core.Graphics
{ {
__object.Set("line_to", JsValue.FromObject(engine, (object)line_to)); __object.Set("line_to", JsValue.FromObject(engine, (object)line_to));
__object.Set("move_to", JsValue.FromObject(engine, (object)move_to)); __object.Set("move_to", JsValue.FromObject(engine, (object)move_to));
__object.Set("quad_to", JsValue.FromObject(engine, (object)quad_to));
} }
} }
void line_to(float x, float y) => Commands.Add(new LineToCmd(x, y)); void line_to(float x, float y) => Commands.Add(new LineToCmd(x, y));
void move_to(float x, float y) => Commands.Add(new MoveToCmd(x, y)); void move_to(float x, float y) => Commands.Add(new MoveToCmd(x, y));
void quad_to(float x0, float y0, float x1, float y1) => Commands.Add(new QuadToCmd(x0, y0, x1, y1));
public override void Render(RenderContext context) public override void Render(RenderContext context)
{ {

View File

@@ -17,6 +17,21 @@ namespace Progrart.Core.Graphics
path.LineTo(pos); path.LineTo(pos);
} }
} }
public class QuadToCmd(float x1, float y1, float x2, float y2) : PathCmd
{
public readonly float x1 = x1;
public readonly float y1 = y1;
private readonly float x2 = x2;
private readonly float y2 = y2;
public override void ApplyCommand(RenderContext context, SKPath path)
{
base.ApplyCommand(context, path);
var pos = context.TranslatePoint(x1, y1);
var pos2 = context.TranslatePoint(x2, y2);
path.QuadTo(pos, pos2);
}
}
public class MoveToCmd(float x, float y) : PathCmd public class MoveToCmd(float x, float y) : PathCmd
{ {
public readonly float x = x; public readonly float x = x;

View File

@@ -9,8 +9,6 @@ namespace Progrart.Core.Graphics
public class PathElement : BaseElement public class PathElement : BaseElement
{ {
float StrokeWidth; float StrokeWidth;
SKPoint Start;
SKPoint End;
SKColorF Color; SKColorF Color;
SKShader? shader = null; SKShader? shader = null;
public override void SetupProperties(Engine engine) public override void SetupProperties(Engine engine)

View File

@@ -1,7 +1,7 @@
Microsoft Visual Studio Solution File, Format Version 12.00 Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 18 # Visual Studio Version 18
VisualStudioVersion = 18.3.11222.16 d18.3 VisualStudioVersion = 18.3.11222.16
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Progrart", "Progrart\Progrart.csproj", "{EBFA8512-1EA5-4D8C-B4AC-AB5B48A6D568}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Progrart", "Progrart\Progrart.csproj", "{EBFA8512-1EA5-4D8C-B4AC-AB5B48A6D568}"
EndProject EndProject
@@ -20,6 +20,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Progrart.Core", "Progrart.Core\Progrart.Core.csproj", "{A691B4C5-777C-4AAA-B402-237372B34F15}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Progrart.Core", "Progrart.Core\Progrart.Core.csproj", "{A691B4C5-777C-4AAA-B402-237372B34F15}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Progrart.Cmd", "Progrart.Cmd\Progrart.Cmd.csproj", "{81803E2B-2EBC-4B11-8B3B-E9278166921B}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@@ -52,6 +54,10 @@ Global
{A691B4C5-777C-4AAA-B402-237372B34F15}.Debug|Any CPU.Build.0 = Debug|Any CPU {A691B4C5-777C-4AAA-B402-237372B34F15}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A691B4C5-777C-4AAA-B402-237372B34F15}.Release|Any CPU.ActiveCfg = Release|Any CPU {A691B4C5-777C-4AAA-B402-237372B34F15}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A691B4C5-777C-4AAA-B402-237372B34F15}.Release|Any CPU.Build.0 = Release|Any CPU {A691B4C5-777C-4AAA-B402-237372B34F15}.Release|Any CPU.Build.0 = Release|Any CPU
{81803E2B-2EBC-4B11-8B3B-E9278166921B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{81803E2B-2EBC-4B11-8B3B-E9278166921B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{81803E2B-2EBC-4B11-8B3B-E9278166921B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{81803E2B-2EBC-4B11-8B3B-E9278166921B}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE

View File

@@ -26,6 +26,7 @@ public partial class App : Application
EditorProvider.Register("text", "Default Text Editor", typeof(EditorPage)); EditorProvider.Register("text", "Default Text Editor", typeof(EditorPage));
EditorProvider.Register("image", "Default Image Viewer", typeof(ImageViewPage)); EditorProvider.Register("image", "Default Image Viewer", typeof(ImageViewPage));
EditorProvider.Register("progrart", "Default Progrart Editor", typeof(ProgrartEditorPage)); EditorProvider.Register("progrart", "Default Progrart Editor", typeof(ProgrartEditorPage));
EditorProvider.Register("project", "Progrart Project Editor", typeof(ProjectEditor));
EditorProvider.Register("console", "Console", typeof(Console)); EditorProvider.Register("console", "Console", typeof(Console));
EditorProvider.BindFileType("cs", "text"); EditorProvider.BindFileType("cs", "text");
EditorProvider.BindFileType("c", "text"); EditorProvider.BindFileType("c", "text");
@@ -42,6 +43,7 @@ public partial class App : Application
EditorProvider.BindFileType("png", "image"); EditorProvider.BindFileType("png", "image");
EditorProvider.BindFileType("bmp", "image"); EditorProvider.BindFileType("bmp", "image");
EditorProvider.BindFileType("jpg", "image"); EditorProvider.BindFileType("jpg", "image");
EditorProvider.BindFileType("progrart-project", "project");
EditorProvider.BindFileType("wd", "console"); EditorProvider.BindFileType("wd", "console");
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{ {

View File

@@ -0,0 +1,37 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:Progrart.Controls"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Progrart.Controls.ConfigEditor">
<StackPanel>
<TextBlock Name="NameBlock" FontSize="18" Text="{Binding #NameBox.Text}"/>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<TextBlock Padding="8,2" VerticalAlignment="Center">Name</TextBlock>
<TextBox Grid.Column="1" Name="NameBox"/>
<TextBlock Padding="8,2" Grid.Row="1" VerticalAlignment="Center">Output</TextBlock>
<TextBox Grid.Column="1" Grid.Row="1" Name="OutputDirBox"/>
</Grid>
<local:ExecuteArgumentsEditor/>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock FontSize="13" VerticalAlignment="Center">Targets</TextBlock>
<Button Name="AddButton" Grid.Column="1" Padding="16,2" VerticalAlignment="Center">+</Button>
</Grid>
<StackPanel Name="ConfigurationHolder">
</StackPanel>
</StackPanel>
</UserControl>

View File

@@ -0,0 +1,11 @@
using Avalonia.Controls;
namespace Progrart.Controls;
public partial class ConfigEditor : UserControl
{
public ConfigEditor()
{
InitializeComponent();
}
}

View File

@@ -0,0 +1,30 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Progrart.Controls.ExecuteArgumentItem" Margin="5,5">
<UserControl.Styles>
<Style Selector="TextBlock">
<Setter Property="VerticalAlignment" Value="Center"/>
</Style>
</UserControl.Styles>
<Border CornerRadius="5" Grid.ColumnSpan="3" Grid.RowSpan="2" Background="#3888" Padding="5">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Padding="8,0">Key</TextBlock>
<TextBlock Padding="8,0" Grid.Row="1">Value</TextBlock>
<TextBox Grid.Column="1" Name="KeyBox"/>
<TextBox Grid.Column="1" Name="ValueBox" Grid.Row="1"/>
<Button Name="RemoveBtn" Padding="16,4" Content="-" Grid.RowSpan="2" VerticalAlignment="Top" Grid.Column="2"/>
</Grid>
</Border>
</UserControl>

View File

@@ -0,0 +1,31 @@
using Avalonia.Controls;
namespace Progrart.Controls;
public partial class ExecuteArgumentItem : UserControl
{
public ExecuteArgumentItem()
{
InitializeComponent();
Init();
}
public ExecuteArgumentItem(string key, string value)
{
InitializeComponent();
Init();
KeyBox.Text = key;
ValueBox.Text = value;
}
void Init()
{
RemoveBtn.Click += (_, _) =>
{
if (this.Parent is StackPanel panel)
{
panel.Children.Remove(this);
}
};
}
public (string, string) GetItme() => (KeyBox.Text ?? "", ValueBox.Text ?? "");
}

View File

@@ -0,0 +1,22 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Progrart.Controls.ExecuteArgumentsEditor">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Text="Arguments" VerticalAlignment="Center"/>
<Button Name="AddButton" Grid.Column="1" Padding="16,2" VerticalAlignment="Center">+</Button>
</Grid>
<StackPanel Grid.Row="1" Name="ItemHolder"></StackPanel>
</Grid>
</UserControl>

View File

@@ -0,0 +1,25 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
using Progrart.Core;
namespace Progrart.Controls;
public partial class ExecuteArgumentsEditor : UserControl
{
public ExecuteArgumentsEditor()
{
InitializeComponent();
AddButton.Click += (_, _) =>
{
ItemHolder.Children.Add(new ExecuteArgumentItem());
};
}
public void LoadArguments(ExecuteArguments args)
{
foreach (var item in args.data)
{
ItemHolder.Children.Add(new ExecuteArgumentItem(item.Key, item.Value));
}
}
}

View File

@@ -0,0 +1,37 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:controls="using:Progrart.Controls"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Progrart.Pages.ProjectEditor">
<UserControl.Styles>
<Style Selector="TextBox">
<Setter Property="Padding" Value="4,2"/>
<Setter Property="MinHeight" Value="0"/>
</Style>
</UserControl.Styles>
<ScrollViewer>
<StackPanel>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBlock Padding="8,2" VerticalAlignment="Center">Output</TextBlock>
<TextBox Grid.Column="1" Name="OutputDirBox"/>
</Grid>
<controls:ExecuteArgumentsEditor Name="ProjectWideArguments"/>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock FontSize="13" VerticalAlignment="Center">Configurations</TextBlock>
<Button Name="AddButton" Grid.Column="1" Padding="16,2" VerticalAlignment="Center">+</Button>
</Grid>
<StackPanel Name="ConfigurationHolder">
</StackPanel>
</StackPanel>
</ScrollViewer>
</UserControl>

View File

@@ -0,0 +1,55 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
using Avalonia.Platform.Storage;
using Progrart.Controls;
using Progrart.Controls.TabSystem;
using Progrart.Core;
using System;
using System.Threading.Tasks;
namespace Progrart.Pages;
public partial class ProjectEditor : UserControl, ITabPage, IEditorPage
{
public ProjectEditor()
{
InitializeComponent();
AddButton.Click += (_, _) =>
{
ConfigurationHolder.Children.Add(new ConfigEditor());
};
}
public void Execute(ExecuteArguments? args = null)
{
}
public bool IsSameFile(IStorageFile file)
{
return (this.file?.Path == file.Path);
}
IStorageFile? file = null;
public void LoadDocument(IStorageFile file)
{
this.file = file;
}
public async Task Save()
{
}
public void SetHost(TabHost host)
{
}
public void BindButton(TabButton button)
{
button.Title = "Project";
}
public bool IsModified()
{
return true;
}
}