diff --git a/Directory.Packages.props b/Directory.Packages.props
index 634d3512d..fd3dfb6b9 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -13,6 +13,7 @@
+
diff --git a/SukiUI.Demo/Common/StorageService.cs b/SukiUI.Demo/Common/StorageService.cs
new file mode 100644
index 000000000..5c1435794
--- /dev/null
+++ b/SukiUI.Demo/Common/StorageService.cs
@@ -0,0 +1,45 @@
+using Avalonia.Controls;
+using Avalonia.Controls.ApplicationLifetimes;
+using Avalonia.Platform.Storage;
+using Avalonia.VisualTree;
+
+namespace SukiUI.Demo.Common
+{
+ internal static class StorageService
+ {
+ public static FilePickerFileType All { get; } = new("All")
+ {
+ Patterns = ["*.*"],
+ MimeTypes = ["*/*"]
+ };
+
+ public static FilePickerFileType Json { get; } = new("Json")
+ {
+ Patterns = ["*.json"],
+ AppleUniformTypeIdentifiers = ["public.json"],
+ MimeTypes = ["application/json"]
+ };
+
+ public static IStorageProvider? GetStorageProvider()
+ {
+ if (Avalonia.Application.Current?.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime { MainWindow: { } window })
+ {
+ return window.StorageProvider;
+ }
+
+ if (Avalonia.Application.Current?.ApplicationLifetime is ISingleViewApplicationLifetime
+ {
+ MainView: { } mainView
+ })
+ {
+ var visualRoot = mainView.GetVisualRoot();
+ if (visualRoot is TopLevel topLevel)
+ {
+ return topLevel.StorageProvider;
+ }
+ }
+
+ return null;
+ }
+ }
+}
\ No newline at end of file
diff --git a/SukiUI.Demo/Features/ControlsLibrary/DockControls/DockFactory.cs b/SukiUI.Demo/Features/ControlsLibrary/DockControls/DockFactory.cs
index 70516629a..0de38ec92 100644
--- a/SukiUI.Demo/Features/ControlsLibrary/DockControls/DockFactory.cs
+++ b/SukiUI.Demo/Features/ControlsLibrary/DockControls/DockFactory.cs
@@ -6,11 +6,10 @@
namespace SukiUI.Demo.Features.ControlsLibrary.DockControls
{
- public class DockFactory(object context) : Factory
+ public class DockFactory(DockMvvmViewModel context) : Factory
{
- private readonly object _context = context;
+ private readonly DockMvvmViewModel _context = context;
private IRootDock? _rootDock;
- private IDocumentDock? _documentDock;
public override IRootDock CreateLayout()
{
@@ -37,7 +36,7 @@ public override IRootDock CreateLayout()
{
ActiveDockable = solutionExploreTool,
VisibleDockables = CreateList(solutionExploreTool),
- Alignment = Alignment.Left
+ Alignment = Alignment.Left,
}
)
};
@@ -64,7 +63,7 @@ public override IRootDock CreateLayout()
{
ActiveDockable = propertiesTool,
VisibleDockables = CreateList(propertiesTool),
- Alignment = Alignment.Top,
+ Alignment = Alignment.Right,
}
)
};
@@ -80,7 +79,7 @@ public override IRootDock CreateLayout()
{
ActiveDockable = outputTool,
VisibleDockables = CreateList(errorListTool, outputTool),
- Alignment = Alignment.Top,
+ Alignment = Alignment.Bottom,
}
)
};
@@ -123,8 +122,7 @@ public override IRootDock CreateLayout()
rootDock.ActiveDockable = homeView;
rootDock.DefaultDockable = homeView;
rootDock.VisibleDockables = CreateList(homeView);
-
- _documentDock = documentDock;
+
_rootDock = rootDock;
return rootDock;
@@ -146,14 +144,12 @@ public override void InitLayout(IDockable layout)
{
ContextLocator = new Dictionary>
{
- ["Dashboard"] = () => layout,
["Home"] = () => _context
};
DockableLocator = new Dictionary>()
{
- ["Root"] = () => _rootDock,
- ["Documents"] = () => _documentDock
+ ["Home"] = () => _rootDock,
};
HostWindowLocator = new Dictionary>
diff --git a/SukiUI.Demo/Features/ControlsLibrary/DockMvvmView.axaml b/SukiUI.Demo/Features/ControlsLibrary/DockMvvmView.axaml
index 85040674e..6a4479793 100644
--- a/SukiUI.Demo/Features/ControlsLibrary/DockMvvmView.axaml
+++ b/SukiUI.Demo/Features/ControlsLibrary/DockMvvmView.axaml
@@ -3,11 +3,50 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:controlsLibrary="clr-namespace:SukiUI.Demo.Features.ControlsLibrary"
+ xmlns:avalonia="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:DataType="controlsLibrary:DockMvvmViewModel"
x:Class="SukiUI.Demo.Features.ControlsLibrary.DockMvvmView">
-
+
+
+
+
+
+
+
+
+
diff --git a/SukiUI.Demo/Features/ControlsLibrary/DockMvvmViewModel.cs b/SukiUI.Demo/Features/ControlsLibrary/DockMvvmViewModel.cs
index 94124668d..192b21ffa 100644
--- a/SukiUI.Demo/Features/ControlsLibrary/DockMvvmViewModel.cs
+++ b/SukiUI.Demo/Features/ControlsLibrary/DockMvvmViewModel.cs
@@ -1,41 +1,119 @@
using System.Diagnostics;
-using System.Windows.Input;
+using Avalonia.Collections;
+using Avalonia.Platform.Storage;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using Dock.Model.Controls;
using Dock.Model.Core;
+using Dock.Serializer;
using Material.Icons;
+using SukiUI.Demo.Common;
using SukiUI.Demo.Features.ControlsLibrary.DockControls;
namespace SukiUI.Demo.Features.ControlsLibrary
{
public partial class DockMvvmViewModel : DemoPageBase
{
- private readonly IFactory? _factory;
+ private readonly IDockSerializer _serializer;
+ private readonly IFactory _factory;
[ObservableProperty] private IRootDock? _layout;
- public ICommand NewLayout { get; }
-
public DockMvvmViewModel() : base("DockMvvm", MaterialIconKind.DockTop)
{
- _factory = new DockFactory(new object());
-
+ _serializer = new DockSerializer(typeof(AvaloniaList<>));
+ _factory = new DockFactory(this);
DebugFactoryEvents(_factory);
- Layout = _factory?.CreateLayout();
+ Layout = _factory.CreateLayout();
+
+ if (Layout is null)
+ {
+ return;
+ }
+
+ _factory.InitLayout(Layout);
+
+ if (Layout is { } root)
+ {
+ root.Navigate.Execute("Home");
+ }
+ }
+
+ [RelayCommand]
+ private async Task SaveLayout()
+ {
+ var storageProvider = StorageService.GetStorageProvider();
- if (Layout is { })
+ var file = await storageProvider!.SaveFilePickerAsync(new FilePickerSaveOptions
{
- _factory?.InitLayout(Layout);
+ Title = "Save layout",
+ FileTypeChoices = GetOpenLayoutFileTypes(),
+ SuggestedFileName = "layout",
+ DefaultExtension = "json",
+ ShowOverwritePrompt = true
+ });
- if (Layout is { } root)
+ if (file is not null)
+ {
+ try
+ {
+ await using var stream = await file.OpenWriteAsync();
+
+ if (Layout is not null)
+ {
+ _serializer.Save(stream, Layout);
+ }
+ }
+ catch (Exception e)
{
- root.Navigate.Execute("Home");
+ Console.WriteLine(e);
}
}
+ }
+
+ [RelayCommand]
+ private async Task OpenLayout()
+ {
+ var storageProvider = StorageService.GetStorageProvider();
+
+ var result = await storageProvider!.OpenFilePickerAsync(
+ new FilePickerOpenOptions
+ {
+ Title = "Open layout",
+ FileTypeFilter = GetOpenLayoutFileTypes(),
+ AllowMultiple = false
+ });
+
+ var file = result.FirstOrDefault();
+
+ if (file is not null)
+ {
+ try
+ {
+ await using var stream = await file.OpenReadAsync();
+ using var reader = new StreamReader(stream);
+
+ var layout = _serializer.Load(stream);
- NewLayout = new RelayCommand(ResetLayout);
+ if (layout is not null)
+ {
+ _factory!.InitLayout(layout);
+ Layout = layout;
+ }
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e);
+ }
+ }
}
+
+ private static List GetOpenLayoutFileTypes()
+ =>
+ [
+ StorageService.Json,
+ StorageService.All
+ ];
private static void DebugFactoryEvents(IFactory factory)
{
@@ -136,31 +214,5 @@ private static void DebugFactoryEvents(IFactory factory)
$"[WindowMoveDragEnd] Title='{args.Window?.Title}', X='{args.Window?.X}', Y='{args.Window?.Y}");
};
}
-
- public void CloseLayout()
- {
- if (Layout is IDock dock && dock.Close.CanExecute(null))
- {
- dock.Close.Execute(null);
- }
- }
-
- public void ResetLayout()
- {
- if (Layout is not null && Layout.Close.CanExecute(null))
- {
- Layout.Close.Execute(null);
- }
-
- var layout = _factory?.CreateLayout();
-
- if (layout is null)
- {
- return;
- }
-
- Layout = layout;
- _factory?.InitLayout(layout);
- }
}
}
\ No newline at end of file
diff --git a/SukiUI.Demo/Program.cs b/SukiUI.Demo/Program.cs
index 4ded44565..ff6965435 100644
--- a/SukiUI.Demo/Program.cs
+++ b/SukiUI.Demo/Program.cs
@@ -24,7 +24,10 @@ public static AppBuilder BuildAvaloniaApp()
.UseXamlDisplay();
if (OperatingSystem.IsWindows() || OperatingSystem.IsMacOS() || OperatingSystem.IsLinux())
- app.UseManagedSystemDialogs();
+ {
+ //app.UseManagedSystemDialogs();
+ }
+
return app;
}
}
\ No newline at end of file
diff --git a/SukiUI.Demo/SukiUI.Demo.csproj b/SukiUI.Demo/SukiUI.Demo.csproj
index 9c62f3928..64c8b6f3a 100644
--- a/SukiUI.Demo/SukiUI.Demo.csproj
+++ b/SukiUI.Demo/SukiUI.Demo.csproj
@@ -27,6 +27,7 @@
+