Implemented a settings page and settings provider.

This commit is contained in:
Creeper Lv
2026-01-18 03:14:22 +11:00
parent 6dff9b8718
commit 365be0474a
11 changed files with 224 additions and 16 deletions

View File

@@ -19,6 +19,8 @@
<PackageVersion Include="Deadpikle.AvaloniaProgressRing" Version="0.10.11-preview20251127001" /> <PackageVersion Include="Deadpikle.AvaloniaProgressRing" Version="0.10.11-preview20251127001" />
<PackageVersion Include="DialogHost.Avalonia" Version="0.10.4" /> <PackageVersion Include="DialogHost.Avalonia" Version="0.10.4" />
<PackageVersion Include="Jint" Version="4.5.0" /> <PackageVersion Include="Jint" Version="4.5.0" />
<PackageVersion Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="10.0.2" />
<PackageVersion Include="Microsoft.Extensions.Configuration.Json" Version="10.0.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="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.23.0" />

View File

@@ -1,14 +1,18 @@
using System.Runtime.Versioning; using Avalonia;
using System.Threading.Tasks;
using Avalonia;
using Avalonia.Browser; using Avalonia.Browser;
using Progrart; using Progrart;
using Progrart.Browser.Settings;
using System.Threading.Tasks;
internal sealed partial class Program internal sealed partial class Program
{ {
private static Task Main(string[] args) => BuildAvaloniaApp() private static Task Main(string[] args)
{
App.SettingsProvider=new BrowserSettingsProvider();
return BuildAvaloniaApp()
.WithInterFont() .WithInterFont()
.StartBrowserAppAsync("out"); .StartBrowserAppAsync("out");
}
public static AppBuilder BuildAvaloniaApp() public static AppBuilder BuildAvaloniaApp()
=> AppBuilder.Configure<App>(); => AppBuilder.Configure<App>();

View File

@@ -0,0 +1,29 @@
using Progrart.Core.Settings;
using System.Runtime.InteropServices.JavaScript;
using System.Text.Json;
namespace Progrart.Browser.Settings
{
public partial class BrowserSettingsProvider : ISettingsProvider
{
private SerializeContext context=new SerializeContext();
[JSImport("globalThis.localStorage.setItem")]
private static partial void SetItem(string key, string value);
[JSImport("globalThis.localStorage.getItem")]
private static partial string GetItem(string key);
public AppConfig LoadSettings()
{
var json = GetItem("progrart.settings");
return json != null
? JsonSerializer.Deserialize<AppConfig>(json,context.AppConfig)??new AppConfig()
: new AppConfig();
}
public void SaveSettings(AppConfig config)
{
var json = JsonSerializer.Serialize(config,context.AppConfig)??"";
SetItem("progrart.settings", json);
}
}
}

View File

@@ -2,14 +2,16 @@ using Avalonia;
using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Data.Core; using Avalonia.Data.Core;
using Avalonia.Data.Core.Plugins; using Avalonia.Data.Core.Plugins;
using System.Linq;
using Avalonia.Markup.Xaml; using Avalonia.Markup.Xaml;
using Progrart.Views; using Avalonia.Platform.Storage;
using Microsoft.Extensions.Configuration;
using Progrart.Core.ProjectSystem;
using Progrart.Core.Settings;
using Progrart.Icons; using Progrart.Icons;
using Progrart.Pages; using Progrart.Pages;
using Avalonia.Platform.Storage; using Progrart.Views;
using System; using System;
using Progrart.Core.ProjectSystem; using System.Linq;
namespace Progrart; namespace Progrart;
@@ -19,6 +21,7 @@ public partial class App : Application
public static IStorageFolder? CurrentOpenFolder = null; public static IStorageFolder? CurrentOpenFolder = null;
public static Project? LoadedProject = null; public static Project? LoadedProject = null;
internal static Action? ProjectLoadHandler = null; internal static Action? ProjectLoadHandler = null;
public static ISettingsProvider? SettingsProvider = null;
public static void ProjectLoad() public static void ProjectLoad()
{ {
ProjectLoadHandler?.Invoke(); ProjectLoadHandler?.Invoke();
@@ -27,7 +30,6 @@ public partial class App : Application
{ {
AvaloniaXamlLoader.Load(this); AvaloniaXamlLoader.Load(this);
} }
public override void OnFrameworkInitializationCompleted() public override void OnFrameworkInitializationCompleted()
{ {
IconProvider.Register(new DefaultIconProvider()); IconProvider.Register(new DefaultIconProvider());
@@ -53,6 +55,10 @@ public partial class App : Application
EditorProvider.BindFileType("jpg", "image"); EditorProvider.BindFileType("jpg", "image");
EditorProvider.BindFileType("progrart-project", "project"); EditorProvider.BindFileType("progrart-project", "project");
EditorProvider.BindFileType("wd", "console"); EditorProvider.BindFileType("wd", "console");
if (!OperatingSystem.IsBrowser())
{
App.SettingsProvider = new ClassicSettingsProvider();
}
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{ {
// Avoid duplicate validations from both Avalonia and the CommunityToolkit. // Avoid duplicate validations from both Avalonia and the CommunityToolkit.

View File

@@ -0,0 +1,33 @@
using System;
using System.IO;
using System.Text.Json;
namespace Progrart.Core.Settings
{
public class ClassicSettingsProvider : ISettingsProvider
{
private readonly string _filePath;
private SerializeContext context = new SerializeContext();
public ClassicSettingsProvider()
{
var folder = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
var appFolder = Path.Combine(folder, "Progrart");
Directory.CreateDirectory(appFolder);
_filePath = Path.Combine(appFolder, "settings.json");
}
public void SaveSettings(AppConfig settings)
{
var json = JsonSerializer.Serialize(settings, context.AppConfig);
File.WriteAllText(_filePath, json);
}
public AppConfig LoadSettings()
{
if (!File.Exists(_filePath)) return new AppConfig();
var json = File.ReadAllText(_filePath);
return JsonSerializer.Deserialize<AppConfig>(json, context.AppConfig) ?? new AppConfig();
}
}
}

View File

@@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.Json.Serialization;
namespace Progrart.Core.Settings
{
public interface ISettingsProvider
{
void SaveSettings(AppConfig config);
AppConfig LoadSettings();
}
[Serializable]
public class AppConfig
{
public bool useParallelBuild { get; set; }
public int JobCount { get; set; }
}
[JsonSerializable(typeof(AppConfig))]
public partial class SerializeContext : JsonSerializerContext
{
}
}

View File

@@ -0,0 +1,47 @@
<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.Pages.SettingsPage">
<UserControl.Styles>
<Style Selector="TextBlock.h1">
<Setter Property="FontSize" Value="20"/>
<Setter Property="Margin" Value="5"/>
</Style>
<Style Selector="TextBlock.h2">
<Setter Property="FontSize" Value="18"/>
<Setter Property="Margin" Value="5"/>
</Style>
<Style Selector="Expander">
<Setter Property="HorizontalAlignment" Value="Stretch"/>
</Style>
</UserControl.Styles>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid>
<TextBlock Text="Settings" Classes="h1" VerticalAlignment="Center"/>
<Button Name="SaveSettings" HorizontalAlignment="Right" VerticalAlignment="Center" Click="SaveSettings_Click">
<PathIcon Data="F1 M 3.36 11.959999 C 3.28 11.853333 3.173333 11.799999 3.04 11.799999 C 2.906667 11.799999 2.786666 11.846666 2.68 11.94 C 2.573333 12.033334 2.513333 12.146667 2.5 12.28 C 2.486667 12.413334 2.533333 12.533333 2.64 12.639999 L 6.64 17.119999 C 6.719999 17.226665 6.833333 17.286667 6.98 17.299999 C 7.126667 17.313332 7.253333 17.266666 7.36 17.16 L 17.84 6.639999 C 17.946667 6.56 18 6.446667 18 6.299999 C 18 6.153334 17.953331 6.033334 17.859999 5.94 C 17.766666 5.846666 17.646666 5.799999 17.5 5.799999 C 17.353333 5.799999 17.239998 5.853333 17.16 5.96 L 7.04 16.08 Z " VerticalAlignment="Center" HorizontalAlignment="Center" />
</Button>
</Grid>
<ScrollViewer Grid.Row="1">
<StackPanel>
<Expander>
<Expander.Header>
<TextBlock Text="Builder" Classes="h2"/>
</Expander.Header>
<StackPanel Margin="10">
<TextBlock>Use Parallel Building</TextBlock>
<ToggleSwitch Name="useParallelBuilding"/>
<TextBlock Text="Job Count ( -1 for Processor Count)" VerticalAlignment="Center" TextWrapping="Wrap"/>
<NumericUpDown Minimum="-1" Maximum="1024" Value="-1" Name="JobCont" FormatString="0" HorizontalAlignment="Left"/>
</StackPanel>
</Expander>
</StackPanel>
</ScrollViewer>
</Grid>
</UserControl>

View File

@@ -0,0 +1,51 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
using Microsoft.Extensions.Configuration;
using Progrart.Controls.TabSystem;
using Progrart.Core.Settings;
namespace Progrart.Pages;
public partial class SettingsPage : UserControl, ITabPage
{
public SettingsPage()
{
InitializeComponent();
if ((App.SettingsProvider) != null)
{
var settings = App.SettingsProvider.LoadSettings();
{
useParallelBuilding.IsChecked = settings.useParallelBuild;
JobCont.Value = settings.JobCount;
}
}
}
public void BindButton(TabButton button)
{
button.Title = "Settings";
}
public bool IsModified()
{
return false;
}
public void SetHost(TabHost host)
{
}
private void SaveSettings_Click(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
{
if (App.SettingsProvider is null) return;
AppConfig config = new AppConfig()
{
useParallelBuild = useParallelBuilding.IsChecked ?? false,
JobCount = (int)(JobCont.Value ?? -1)
};
App.SettingsProvider.SaveSettings(config);
}
}

View File

@@ -28,6 +28,8 @@
<PackageReference Include="AvaloniaEdit.TextMate" /> <PackageReference Include="AvaloniaEdit.TextMate" />
<PackageReference Include="Deadpikle.AvaloniaProgressRing" /> <PackageReference Include="Deadpikle.AvaloniaProgressRing" />
<PackageReference Include="DialogHost.Avalonia" /> <PackageReference Include="DialogHost.Avalonia" />
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" />
<PackageReference Include="PanAndZoom" /> <PackageReference Include="PanAndZoom" />
<!--<PackageReference Include="Devolutions.AvaloniaTheme.DevExpress" /> <!--<PackageReference Include="Devolutions.AvaloniaTheme.DevExpress" />
<PackageReference Include="Devolutions.AvaloniaTheme.MacOS" />--> <PackageReference Include="Devolutions.AvaloniaTheme.MacOS" />-->

View File

@@ -50,7 +50,7 @@
<MenuItem Header="Save _As"/> <MenuItem Header="Save _As"/>
</MenuItem> </MenuItem>
<MenuItem Header="_Tools"> <MenuItem Header="_Tools">
<MenuItem Header="_Settings"/> <MenuItem Header="_Settings" Name="SettingsMenuItem" Click="SettingsMenuItem_Click"/>
</MenuItem> </MenuItem>
<MenuItem Header="_Help"> <MenuItem Header="_Help">
<MenuItem Header="_About" Name="AboutItem"/> <MenuItem Header="_About" Name="AboutItem"/>

View File

@@ -2,12 +2,14 @@ using Acornima.Ast;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Platform.Storage; using Avalonia.Platform.Storage;
using Avalonia.Threading; using Avalonia.Threading;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json; using Newtonsoft.Json;
using Progrart.Commands; using Progrart.Commands;
using Progrart.Controls; using Progrart.Controls;
using Progrart.Core; using Progrart.Core;
using Progrart.Core.JSExecution; using Progrart.Core.JSExecution;
using Progrart.Core.ProjectSystem; using Progrart.Core.ProjectSystem;
using Progrart.Core.Settings;
using Progrart.Core.Storage; using Progrart.Core.Storage;
using Progrart.Pages; using Progrart.Pages;
using System; using System;
@@ -264,7 +266,15 @@ public partial class MainView : UserControl
ProgressGrid.IsVisible = false; ProgressGrid.IsVisible = false;
}); });
}; };
Task.Run(async () => await builder.Build(name, -1)); AppConfig app_config = new AppConfig();
if (App.SettingsProvider != null)
app_config = App.SettingsProvider.LoadSettings();
Task.Run(async () => await builder.Build(name, app_config.useParallelBuild == false ? 1 : app_config.JobCount));
} }
} }
private void SettingsMenuItem_Click(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
{
MainTabHost.AddPage(new SettingsPage());
}
} }