From d909f41d7e0573fb949a23f8cf7c85b4da7e9e29 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Fri, 20 Mar 2026 17:19:23 +0000
Subject: [PATCH 1/4] Merge remote-tracking branch 'origin/avalonia-port' into
copilot/prepare-port-wpf-ui-to-avalonia
---
.gitignore | 2 ++
ControlPad.sln | 14 ++++++++++++++
2 files changed, 16 insertions(+)
diff --git a/.gitignore b/.gitignore
index bd2a898..0ac0951 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,6 +5,8 @@
ControlPad/bin/
ControlPad/obj/
ControlPad/publish/
+ControlPad.Avalonia/bin/
+ControlPad.Avalonia/obj/
ControlPad.Tests/bin/
ControlPad.Tests/obj/
diff --git a/ControlPad.sln b/ControlPad.sln
index 85baabe..d1dc8ae 100644
--- a/ControlPad.sln
+++ b/ControlPad.sln
@@ -5,6 +5,8 @@ VisualStudioVersion = 17.14.36212.18
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ControlPad", "ControlPad\ControlPad.csproj", "{D35BB3DA-59CF-B3B9-1C64-51118D02B4EA}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ControlPad.Avalonia", "ControlPad.Avalonia\ControlPad.Avalonia.csproj", "{0A31B3E6-246A-4CCA-8E9C-E7B3B38D4874}"
+EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ControlPad.Tests", "ControlPad.Tests\ControlPad.Tests.csproj", "{9BC9BA13-FBC5-47F4-9CAD-8864C84C4AC7}"
EndProject
Global
@@ -29,6 +31,18 @@ Global
{D35BB3DA-59CF-B3B9-1C64-51118D02B4EA}.Release|x64.Build.0 = Release|Any CPU
{D35BB3DA-59CF-B3B9-1C64-51118D02B4EA}.Release|x86.ActiveCfg = Release|Any CPU
{D35BB3DA-59CF-B3B9-1C64-51118D02B4EA}.Release|x86.Build.0 = Release|Any CPU
+ {0A31B3E6-246A-4CCA-8E9C-E7B3B38D4874}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {0A31B3E6-246A-4CCA-8E9C-E7B3B38D4874}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {0A31B3E6-246A-4CCA-8E9C-E7B3B38D4874}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {0A31B3E6-246A-4CCA-8E9C-E7B3B38D4874}.Debug|x64.Build.0 = Debug|Any CPU
+ {0A31B3E6-246A-4CCA-8E9C-E7B3B38D4874}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {0A31B3E6-246A-4CCA-8E9C-E7B3B38D4874}.Debug|x86.Build.0 = Debug|Any CPU
+ {0A31B3E6-246A-4CCA-8E9C-E7B3B38D4874}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {0A31B3E6-246A-4CCA-8E9C-E7B3B38D4874}.Release|Any CPU.Build.0 = Release|Any CPU
+ {0A31B3E6-246A-4CCA-8E9C-E7B3B38D4874}.Release|x64.ActiveCfg = Release|Any CPU
+ {0A31B3E6-246A-4CCA-8E9C-E7B3B38D4874}.Release|x64.Build.0 = Release|Any CPU
+ {0A31B3E6-246A-4CCA-8E9C-E7B3B38D4874}.Release|x86.ActiveCfg = Release|Any CPU
+ {0A31B3E6-246A-4CCA-8E9C-E7B3B38D4874}.Release|x86.Build.0 = Release|Any CPU
{9BC9BA13-FBC5-47F4-9CAD-8864C84C4AC7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9BC9BA13-FBC5-47F4-9CAD-8864C84C4AC7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9BC9BA13-FBC5-47F4-9CAD-8864C84C4AC7}.Debug|x64.ActiveCfg = Debug|Any CPU
From 59fa60735079d38a040655bafe7fa05c2e5779d0 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Fri, 20 Mar 2026 17:21:10 +0000
Subject: [PATCH 2/4] feat: add functional Avalonia page navigation skeleton
Co-authored-by: PalmarHealer <93807726+PalmarHealer@users.noreply.github.com>
Agent-Logs-Url: https://github.com/ControlPad/App/sessions/07626b93-a886-4db8-a206-162ac4c426c2
---
ControlPad.Avalonia/MainWindow.axaml | 50 +++++++++++++++++++
ControlPad.Avalonia/MainWindow.axaml.cs | 38 ++++++++++++++
.../Views/ButtonCategoriesView.axaml | 10 ++++
.../Views/ButtonCategoriesView.axaml.cs | 11 ++++
ControlPad.Avalonia/Views/HomeView.axaml | 10 ++++
ControlPad.Avalonia/Views/HomeView.axaml.cs | 11 ++++
ControlPad.Avalonia/Views/SettingsView.axaml | 10 ++++
.../Views/SettingsView.axaml.cs | 11 ++++
.../Views/SliderCategoriesView.axaml | 10 ++++
.../Views/SliderCategoriesView.axaml.cs | 11 ++++
README.md | 25 ++++++++++
11 files changed, 197 insertions(+)
create mode 100644 ControlPad.Avalonia/MainWindow.axaml
create mode 100644 ControlPad.Avalonia/MainWindow.axaml.cs
create mode 100644 ControlPad.Avalonia/Views/ButtonCategoriesView.axaml
create mode 100644 ControlPad.Avalonia/Views/ButtonCategoriesView.axaml.cs
create mode 100644 ControlPad.Avalonia/Views/HomeView.axaml
create mode 100644 ControlPad.Avalonia/Views/HomeView.axaml.cs
create mode 100644 ControlPad.Avalonia/Views/SettingsView.axaml
create mode 100644 ControlPad.Avalonia/Views/SettingsView.axaml.cs
create mode 100644 ControlPad.Avalonia/Views/SliderCategoriesView.axaml
create mode 100644 ControlPad.Avalonia/Views/SliderCategoriesView.axaml.cs
diff --git a/ControlPad.Avalonia/MainWindow.axaml b/ControlPad.Avalonia/MainWindow.axaml
new file mode 100644
index 0000000..c67d120
--- /dev/null
+++ b/ControlPad.Avalonia/MainWindow.axaml
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ControlPad.Avalonia/MainWindow.axaml.cs b/ControlPad.Avalonia/MainWindow.axaml.cs
new file mode 100644
index 0000000..b036e00
--- /dev/null
+++ b/ControlPad.Avalonia/MainWindow.axaml.cs
@@ -0,0 +1,38 @@
+using Avalonia.Controls;
+using Avalonia.Interactivity;
+using ControlPad.Avalonia.Views;
+
+namespace ControlPad.Avalonia;
+
+public partial class MainWindow : Window
+{
+ public MainWindow()
+ {
+ InitializeComponent();
+ }
+
+ private void HomeButton_Click(object? sender, RoutedEventArgs e)
+ {
+ MainContentHost.Content = new HomeView();
+ }
+
+ private void SliderButton_Click(object? sender, RoutedEventArgs e)
+ {
+ MainContentHost.Content = new SliderCategoriesView();
+ }
+
+ private void ButtonButton_Click(object? sender, RoutedEventArgs e)
+ {
+ MainContentHost.Content = new ButtonCategoriesView();
+ }
+
+ private void SettingsButton_Click(object? sender, RoutedEventArgs e)
+ {
+ MainContentHost.Content = new SettingsView();
+ }
+
+ private void ExitButton_Click(object? sender, RoutedEventArgs e)
+ {
+ Close();
+ }
+}
diff --git a/ControlPad.Avalonia/Views/ButtonCategoriesView.axaml b/ControlPad.Avalonia/Views/ButtonCategoriesView.axaml
new file mode 100644
index 0000000..f86a0a3
--- /dev/null
+++ b/ControlPad.Avalonia/Views/ButtonCategoriesView.axaml
@@ -0,0 +1,10 @@
+
+
+
+
+
diff --git a/ControlPad.Avalonia/Views/ButtonCategoriesView.axaml.cs b/ControlPad.Avalonia/Views/ButtonCategoriesView.axaml.cs
new file mode 100644
index 0000000..318a3ab
--- /dev/null
+++ b/ControlPad.Avalonia/Views/ButtonCategoriesView.axaml.cs
@@ -0,0 +1,11 @@
+using Avalonia.Controls;
+
+namespace ControlPad.Avalonia.Views;
+
+public partial class ButtonCategoriesView : UserControl
+{
+ public ButtonCategoriesView()
+ {
+ InitializeComponent();
+ }
+}
diff --git a/ControlPad.Avalonia/Views/HomeView.axaml b/ControlPad.Avalonia/Views/HomeView.axaml
new file mode 100644
index 0000000..54c0bdb
--- /dev/null
+++ b/ControlPad.Avalonia/Views/HomeView.axaml
@@ -0,0 +1,10 @@
+
+
+
+
+
diff --git a/ControlPad.Avalonia/Views/HomeView.axaml.cs b/ControlPad.Avalonia/Views/HomeView.axaml.cs
new file mode 100644
index 0000000..431f964
--- /dev/null
+++ b/ControlPad.Avalonia/Views/HomeView.axaml.cs
@@ -0,0 +1,11 @@
+using Avalonia.Controls;
+
+namespace ControlPad.Avalonia.Views;
+
+public partial class HomeView : UserControl
+{
+ public HomeView()
+ {
+ InitializeComponent();
+ }
+}
diff --git a/ControlPad.Avalonia/Views/SettingsView.axaml b/ControlPad.Avalonia/Views/SettingsView.axaml
new file mode 100644
index 0000000..f4681ea
--- /dev/null
+++ b/ControlPad.Avalonia/Views/SettingsView.axaml
@@ -0,0 +1,10 @@
+
+
+
+
+
diff --git a/ControlPad.Avalonia/Views/SettingsView.axaml.cs b/ControlPad.Avalonia/Views/SettingsView.axaml.cs
new file mode 100644
index 0000000..4fd5899
--- /dev/null
+++ b/ControlPad.Avalonia/Views/SettingsView.axaml.cs
@@ -0,0 +1,11 @@
+using Avalonia.Controls;
+
+namespace ControlPad.Avalonia.Views;
+
+public partial class SettingsView : UserControl
+{
+ public SettingsView()
+ {
+ InitializeComponent();
+ }
+}
diff --git a/ControlPad.Avalonia/Views/SliderCategoriesView.axaml b/ControlPad.Avalonia/Views/SliderCategoriesView.axaml
new file mode 100644
index 0000000..74064ee
--- /dev/null
+++ b/ControlPad.Avalonia/Views/SliderCategoriesView.axaml
@@ -0,0 +1,10 @@
+
+
+
+
+
diff --git a/ControlPad.Avalonia/Views/SliderCategoriesView.axaml.cs b/ControlPad.Avalonia/Views/SliderCategoriesView.axaml.cs
new file mode 100644
index 0000000..c5064cd
--- /dev/null
+++ b/ControlPad.Avalonia/Views/SliderCategoriesView.axaml.cs
@@ -0,0 +1,11 @@
+using Avalonia.Controls;
+
+namespace ControlPad.Avalonia.Views;
+
+public partial class SliderCategoriesView : UserControl
+{
+ public SliderCategoriesView()
+ {
+ InitializeComponent();
+ }
+}
diff --git a/README.md b/README.md
index 00ccb12..8bf2dba 100644
--- a/README.md
+++ b/README.md
@@ -48,6 +48,31 @@ dotnet build ControlPad/ControlPad.csproj -c Release
dotnet run --project ControlPad/ControlPad.csproj
```
+### Avalonia Port (In Progress)
+
+A parallel Avalonia port scaffold now exists at:
+
+`ControlPad.Avalonia/ControlPad.Avalonia.csproj`
+
+Build:
+
+```bash
+dotnet build ControlPad.Avalonia/ControlPad.Avalonia.csproj
+```
+
+Run:
+
+```bash
+dotnet run --project ControlPad.Avalonia/ControlPad.Avalonia.csproj
+```
+
+The existing WPF app in `ControlPad/` remains the primary implementation.
+
+### Tests
+
+```bash
+dotnet test ControlPad.Tests/ControlPad.Tests.csproj
+```
### Publishing
```bash
From ee273c83c68c3c72a0e6a389b842f093ee05f2e2 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Fri, 20 Mar 2026 19:05:39 +0000
Subject: [PATCH 3/4] Restore Avalonia scaffold and continue PR #32 port
Co-authored-by: PalmarHealer <93807726+PalmarHealer@users.noreply.github.com>
Agent-Logs-Url: https://github.com/ControlPad/App/sessions/35cdcae1-1ab6-4f1a-a54e-bca36d497faa
---
ControlPad.Avalonia/App.axaml | 8 +++++++
ControlPad.Avalonia/App.axaml.cs | 23 +++++++++++++++++++
.../ControlPad.Avalonia.csproj | 20 ++++++++++++++++
ControlPad.Avalonia/Program.cs | 17 ++++++++++++++
ControlPad.Avalonia/app.manifest | 10 ++++++++
5 files changed, 78 insertions(+)
create mode 100644 ControlPad.Avalonia/App.axaml
create mode 100644 ControlPad.Avalonia/App.axaml.cs
create mode 100644 ControlPad.Avalonia/ControlPad.Avalonia.csproj
create mode 100644 ControlPad.Avalonia/Program.cs
create mode 100644 ControlPad.Avalonia/app.manifest
diff --git a/ControlPad.Avalonia/App.axaml b/ControlPad.Avalonia/App.axaml
new file mode 100644
index 0000000..708cb56
--- /dev/null
+++ b/ControlPad.Avalonia/App.axaml
@@ -0,0 +1,8 @@
+
+
+
+
+
diff --git a/ControlPad.Avalonia/App.axaml.cs b/ControlPad.Avalonia/App.axaml.cs
new file mode 100644
index 0000000..ad7c4f2
--- /dev/null
+++ b/ControlPad.Avalonia/App.axaml.cs
@@ -0,0 +1,23 @@
+using Avalonia;
+using Avalonia.Controls.ApplicationLifetimes;
+using Avalonia.Markup.Xaml;
+
+namespace ControlPad.Avalonia;
+
+public partial class App : Application
+{
+ public override void Initialize()
+ {
+ AvaloniaXamlLoader.Load(this);
+ }
+
+ public override void OnFrameworkInitializationCompleted()
+ {
+ if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
+ {
+ desktop.MainWindow = new MainWindow();
+ }
+
+ base.OnFrameworkInitializationCompleted();
+ }
+}
diff --git a/ControlPad.Avalonia/ControlPad.Avalonia.csproj b/ControlPad.Avalonia/ControlPad.Avalonia.csproj
new file mode 100644
index 0000000..df2da98
--- /dev/null
+++ b/ControlPad.Avalonia/ControlPad.Avalonia.csproj
@@ -0,0 +1,20 @@
+
+
+ WinExe
+ net9.0
+ enable
+ app.manifest
+ true
+
+
+
+
+
+
+
+
+ None
+ All
+
+
+
diff --git a/ControlPad.Avalonia/Program.cs b/ControlPad.Avalonia/Program.cs
new file mode 100644
index 0000000..1dec41f
--- /dev/null
+++ b/ControlPad.Avalonia/Program.cs
@@ -0,0 +1,17 @@
+using Avalonia;
+using System;
+
+namespace ControlPad.Avalonia;
+
+class Program
+{
+ [STAThread]
+ public static void Main(string[] args) => BuildAvaloniaApp()
+ .StartWithClassicDesktopLifetime(args);
+
+ public static AppBuilder BuildAvaloniaApp()
+ => AppBuilder.Configure()
+ .UsePlatformDetect()
+ .WithInterFont()
+ .LogToTrace();
+}
diff --git a/ControlPad.Avalonia/app.manifest b/ControlPad.Avalonia/app.manifest
new file mode 100644
index 0000000..0de4c7f
--- /dev/null
+++ b/ControlPad.Avalonia/app.manifest
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
From 9229a71f6eeec51a52ac5562d7453fdecb919f97 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Fri, 20 Mar 2026 19:06:35 +0000
Subject: [PATCH 4/4] Reuse Avalonia view instances in navigation host
Co-authored-by: PalmarHealer <93807726+PalmarHealer@users.noreply.github.com>
Agent-Logs-Url: https://github.com/ControlPad/App/sessions/35cdcae1-1ab6-4f1a-a54e-bca36d497faa
---
ControlPad.Avalonia/MainWindow.axaml.cs | 58 ++++++++++++++-----------
1 file changed, 32 insertions(+), 26 deletions(-)
diff --git a/ControlPad.Avalonia/MainWindow.axaml.cs b/ControlPad.Avalonia/MainWindow.axaml.cs
index b036e00..8eb0705 100644
--- a/ControlPad.Avalonia/MainWindow.axaml.cs
+++ b/ControlPad.Avalonia/MainWindow.axaml.cs
@@ -4,32 +4,38 @@
namespace ControlPad.Avalonia;
-public partial class MainWindow : Window
-{
- public MainWindow()
- {
- InitializeComponent();
- }
-
- private void HomeButton_Click(object? sender, RoutedEventArgs e)
- {
- MainContentHost.Content = new HomeView();
- }
-
- private void SliderButton_Click(object? sender, RoutedEventArgs e)
- {
- MainContentHost.Content = new SliderCategoriesView();
- }
-
- private void ButtonButton_Click(object? sender, RoutedEventArgs e)
- {
- MainContentHost.Content = new ButtonCategoriesView();
- }
-
- private void SettingsButton_Click(object? sender, RoutedEventArgs e)
- {
- MainContentHost.Content = new SettingsView();
- }
+public partial class MainWindow : Window
+{
+ private readonly HomeView _homeView = new();
+ private readonly SliderCategoriesView _sliderCategoriesView = new();
+ private readonly ButtonCategoriesView _buttonCategoriesView = new();
+ private readonly SettingsView _settingsView = new();
+
+ public MainWindow()
+ {
+ InitializeComponent();
+ MainContentHost.Content = _homeView;
+ }
+
+ private void HomeButton_Click(object? sender, RoutedEventArgs e)
+ {
+ MainContentHost.Content = _homeView;
+ }
+
+ private void SliderButton_Click(object? sender, RoutedEventArgs e)
+ {
+ MainContentHost.Content = _sliderCategoriesView;
+ }
+
+ private void ButtonButton_Click(object? sender, RoutedEventArgs e)
+ {
+ MainContentHost.Content = _buttonCategoriesView;
+ }
+
+ private void SettingsButton_Click(object? sender, RoutedEventArgs e)
+ {
+ MainContentHost.Content = _settingsView;
+ }
private void ExitButton_Click(object? sender, RoutedEventArgs e)
{