-
Notifications
You must be signed in to change notification settings - Fork 150
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #336 from dme-compunet/native-aot-gallery
Update Gallery for NativeAOT Compatibility
- Loading branch information
Showing
19 changed files
with
340 additions
and
186 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
name: Build Gallery (Native) | ||
|
||
on: | ||
push: | ||
branches: [ "main" ] | ||
pull_request: | ||
branches: [ "main" ] | ||
|
||
jobs: | ||
build: | ||
runs-on: windows-latest | ||
steps: | ||
- name: Checkout | ||
uses: actions/checkout@v4 | ||
|
||
- name: Build Native | ||
run: dotnet publish SukiUI.Demo/SukiUI.Demo.csproj -c Release -r win-x64 -o bin/ | ||
|
||
- name: Upload | ||
uses: actions/upload-artifact@v4 | ||
with: | ||
name: gallery-native | ||
path: bin |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
using Avalonia.Controls; | ||
using Avalonia.Markup.Xaml; | ||
using CommunityToolkit.Mvvm.ComponentModel; | ||
using Microsoft.Extensions.DependencyInjection; | ||
using SukiUI.Demo.Features; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Diagnostics.CodeAnalysis; | ||
|
||
namespace SukiUI.Demo.Common; | ||
|
||
public class SukiViews | ||
{ | ||
private readonly Dictionary<Type, Type> _vmToViewMap = []; | ||
|
||
public SukiViews AddView< | ||
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TView, | ||
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TViewModel>(ServiceCollection services) | ||
where TView : ContentControl | ||
where TViewModel : ObservableObject | ||
{ | ||
var viewType = typeof(TView); | ||
var viewModelType = typeof(TViewModel); | ||
|
||
_vmToViewMap.Add(viewModelType, viewType); | ||
|
||
if (viewModelType.IsAssignableTo(typeof(DemoPageBase))) | ||
{ | ||
services.AddSingleton(typeof(DemoPageBase), viewModelType); | ||
} | ||
else | ||
{ | ||
services.AddSingleton(viewModelType); | ||
} | ||
|
||
return this; | ||
} | ||
|
||
public bool TryCreateView(IServiceProvider provider, Type viewModelType, [NotNullWhen(true)] out Control? view) | ||
{ | ||
var viewModel = provider.GetRequiredService(viewModelType); | ||
|
||
return TryCreateView(viewModel, out view); | ||
} | ||
|
||
public bool TryCreateView(object? viewModel, [NotNullWhen(true)] out Control? view) | ||
{ | ||
view = null; | ||
|
||
if (viewModel == null) | ||
{ | ||
return false; | ||
} | ||
|
||
var viewModelType = viewModel.GetType(); | ||
|
||
if (_vmToViewMap.TryGetValue(viewModelType, out var viewType)) | ||
{ | ||
view = Activator.CreateInstance(viewType) as Control; | ||
|
||
if (view != null) | ||
{ | ||
view.DataContext = viewModel; | ||
} | ||
} | ||
|
||
return view != null; | ||
} | ||
|
||
public Control CreateView<TViewModel>(IServiceProvider provider) where TViewModel : ObservableObject | ||
{ | ||
var viewModelType = typeof(TViewModel); | ||
|
||
if (TryCreateView(provider, viewModelType, out var view)) | ||
{ | ||
return view; | ||
} | ||
|
||
throw new InvalidOperationException(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,39 +1,37 @@ | ||
using Avalonia.Controls; | ||
using Avalonia.Controls.Templates; | ||
using System; | ||
using CommunityToolkit.Mvvm.ComponentModel; | ||
using System.Collections.Generic; | ||
using System.ComponentModel; | ||
|
||
namespace SukiUI.Demo.Common; | ||
|
||
public class ViewLocator : IDataTemplate | ||
public class ViewLocator(SukiViews views) : IDataTemplate | ||
{ | ||
private readonly Dictionary<object, Control> _controlCache = new(); | ||
private readonly Dictionary<object, Control> _controlCache = []; | ||
|
||
public Control Build(object? data) | ||
public Control Build(object? param) | ||
{ | ||
if(data is null) | ||
return new TextBlock { Text = "Data is null." }; | ||
|
||
var fullName = data.GetType().FullName; | ||
|
||
if (string.IsNullOrWhiteSpace(fullName)) | ||
return new TextBlock { Text = "Type has no name, or name is empty." }; | ||
|
||
var name = fullName.Replace("ViewModel", "View"); | ||
var type = Type.GetType(name); | ||
if (type is null) | ||
return new TextBlock { Text = $"No View For {name}." }; | ||
|
||
if (!_controlCache.TryGetValue(data, out var res)) | ||
if (param is null) | ||
{ | ||
res ??= (Control)Activator.CreateInstance(type)!; | ||
_controlCache[data] = res; | ||
return CreateText("Data is null."); | ||
} | ||
|
||
res.DataContext = data; | ||
return res; | ||
if (_controlCache.TryGetValue(param, out var control)) | ||
{ | ||
return control; | ||
} | ||
|
||
if (views.TryCreateView(param, out var view)) | ||
{ | ||
_controlCache.Add(param, view); | ||
|
||
return view; | ||
} | ||
|
||
return CreateText($"No View For {param.GetType().Name}."); | ||
} | ||
|
||
public bool Match(object? data) => data is INotifyPropertyChanged; | ||
public bool Match(object? data) => data is ObservableObject; | ||
|
||
private static TextBlock CreateText(string text) => new TextBlock { Text = text }; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
using Avalonia.Media; | ||
using CommunityToolkit.Mvvm.ComponentModel; | ||
using CommunityToolkit.Mvvm.Input; | ||
using SukiUI.Demo.Services; | ||
using SukiUI.Toasts; | ||
|
||
namespace SukiUI.Demo.Features.ControlsLibrary; | ||
|
||
public partial class IconItemViewModel(ClipboardService clipboard, ISukiToastManager toastManager) : ObservableObject | ||
{ | ||
public required string Name { get; init; } | ||
|
||
public required Geometry Geometry { get; init; } | ||
|
||
[RelayCommand] | ||
public void OnClick() | ||
{ | ||
clipboard.CopyToClipboard($"<PathIcon Data=\"{{x:Static content:Icons.{Name}}}\" />"); | ||
|
||
toastManager | ||
.CreateSimpleInfoToast() | ||
.WithTitle("Copied To Clipboard") | ||
.WithContent($"Copied the XAML for {Name} to your clipboard.") | ||
.Queue(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.