Skip to content

Commit

Permalink
fix full trimming
Browse files Browse the repository at this point in the history
- switch to custom NavigationFactory to avoid reflection
- add SFP and PuppeteerSharp to TrimmerRootAssemblies
- SFP_UI's updatechecker is broken with this, will fix in a future commit
  • Loading branch information
PhantomGamers committed Jun 14, 2023
1 parent 0fcfb7a commit d1540a8
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 78 deletions.
7 changes: 2 additions & 5 deletions SFP_UI/SFP_UI.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@
<PublishSingleFile>true</PublishSingleFile>
<PublishTrimmed>true</PublishTrimmed>
<PublishReadyToRun>true</PublishReadyToRun>
<!--Default TrimMode value breaks app, partial results in larger sizes than avalonia 10 builds so further investigation is needed-->
<TrimMode>partial</TrimMode>
<UseAppHost>true</UseAppHost>
<IncludeNativeLibrariesForSelfExtract>true</IncludeNativeLibrariesForSelfExtract>
</PropertyGroup>
Expand All @@ -28,15 +26,14 @@
<PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Avalonia.Diagnostics" />
<PackageReference Include="Avalonia.ReactiveUI" />
<PackageReference Include="ReactiveUI.Fody">
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Semver" />
<PackageReference Include="FluentAvaloniaUI" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\SFP\SFP.csproj" />
<!--Unsure if this should be SFP or SFP_UI, or if it matters at all!-->
<TrimmerRootAssembly Include="SFP_UI" />
<TrimmerRootAssembly Include="SFP" />
<TrimmerRootAssembly Include="WmiLight" />
<TrimmerRootAssembly Include="PuppeteerSharp" />
</ItemGroup>
</Project>
56 changes: 56 additions & 0 deletions SFP_UI/ViewModels/MainViewViewModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
using Avalonia.Controls;
using FluentAvalonia.UI.Controls;
using SFP_UI.Pages;

namespace SFP_UI.ViewModels;

public class MainViewViewModel : ViewModelBase
{
public MainViewViewModel()
{
NavigationFactory = new NavigationFactory();
}

public NavigationFactory NavigationFactory { get; }
}

public class NavigationFactory : INavigationPageFactory
{
public NavigationFactory()
{
Instance = this;
}

private static NavigationFactory? Instance { get; set; }

// Create a page based on a Type, but you can create it however you want
public Control? GetPage(Type srcType)
{
// Return null here because we won't use this method at all
return null;
}

// Create a page based on an object, such as a view model
public Control? GetPageFromObject(object target)
{
return target switch
{
MainPage => _pages[0],
SettingsPage => _pages[1],
_ => throw new Exception()
};
}

// Do this to avoid needing Activator.CreateInstance to create from type info
// and to avoid a ridiculous amount of 'ifs'
private readonly Control[] _pages =
{
new MainPage(),
new SettingsPage(),
};

public static Control[] GetPages()
{
return Instance!._pages;
}
}
116 changes: 44 additions & 72 deletions SFP_UI/Views/MainView.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,14 @@
using FluentAvalonia.UI.Controls;
using FluentAvalonia.UI.Navigation;
using SFP_UI.Pages;
using SFP_UI.ViewModels;

#endregion

namespace SFP_UI.Views;

public partial class MainView : UserControl
{
private Frame? _frameView;
private NavigationView? _navView;

public MainView()
{
InitializeComponent();
Expand All @@ -25,96 +23,72 @@ protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
{
base.OnAttachedToVisualTree(e);

_frameView = this.FindControl<Frame>("FrameView");
if (_frameView == null)
{
return;
}
var vm = new MainViewViewModel();
DataContext = vm;
FrameView.NavigationPageFactory = vm.NavigationFactory;

_frameView.Navigated += OnFrameViewNavigated;
FrameView.Navigated += OnFrameViewNavigated;
NavView.ItemInvoked += OnNavigationViewItemInvoked;

_navView = this.FindControl<NavigationView>("NavView");
if (_navView != null)
{
_navView.MenuItemsSource = GetNavigationViewItems();
_navView.FooterMenuItemsSource = GetFooterNavigationViewItems();
_navView.ItemInvoked += OnNavigationViewItemInvoked;
_navView.IsPaneOpen = false;
}
NavView.MenuItemsSource = GetNavigationViewItems();
NavView.FooterMenuItemsSource = GetFooterNavigationViewItems();

NavView.IsPaneOpen = false;

_ = _frameView.Navigate(typeof(MainPage));
FrameView.NavigateFromObject(NavView.MenuItemsSource.Cast<NavigationViewItem>().First().Tag!);
}

private void SetNviIcon(NavigationViewItem item, bool selected, bool recurse = false)
private void SetNviIcon(NavigationViewItem? item, bool selected)
{
// Technically, yes you could set up binding and converters and whatnot to let the icon change
// between filled and unfilled based on selection, but this is so much simpler

if (item.Tag is not Type type)
{
if (item == null)
return;
}

if (type == typeof(MainPage))
var t = item.Tag;

item.IconSource = t switch
{
item.IconSource = this.TryFindResource(selected ? "HomeIconFilled" : "HomeIcon", out var value)
MainPage => this.TryFindResource(selected ? "HomeIconFilled" : "HomeIcon", out var value)
? (IconSource)value!
: null;
}
else if (type == typeof(SettingsPage))
{
item.IconSource = this.TryFindResource(selected ? "SettingsIconFilled" : "SettingsIcon", out var value)
: null,
SettingsPage => this.TryFindResource(selected ? "SettingsIconFilled" : "SettingsIcon", out var value)
? (IconSource)value!
: null;
}

if (recurse)
{
return;
}

if (_navView is null)
{
return;
}

var allItems = _navView.MenuItemsSource.Cast<object>()
.Concat(_navView.FooterMenuItemsSource.Cast<object>())
.OfType<NavigationViewItem>();

foreach (var nvi in allItems.Where(nvi => !nvi.Equals(item)))
{
SetNviIcon(nvi, false, true);
}
: null,
_ => item.IconSource
};
}

private void OnFrameViewNavigated(object sender, NavigationEventArgs e)
{
if (_navView != null && !TryNavigateItem(e, _navView.MenuItemsSource))
var page = e.Content as Control;

foreach (NavigationViewItem nvi in NavView.MenuItemsSource)
{
_ = TryNavigateItem(e, _navView.FooterMenuItemsSource);
if (nvi.Tag != null && nvi.Tag.Equals(page))
{
NavView.SelectedItem = nvi;
SetNviIcon(nvi, true);
}
else
{
SetNviIcon(nvi, false);
}
}
}

private bool TryNavigateItem(NavigationEventArgs e, IEnumerable itemsSource)
{
foreach (NavigationViewItem nvi in itemsSource)
foreach (NavigationViewItem nvi in NavView.FooterMenuItemsSource)
{
if (nvi.Tag is not Type tag || tag != e.SourcePageType)
if (nvi.Tag != null && nvi.Tag.Equals(page))
{
continue;
NavView.SelectedItem = nvi;
SetNviIcon(nvi, true);
}

if (_navView != null)
else
{
_navView.SelectedItem = nvi;
SetNviIcon(nvi, false);
}

SetNviIcon(nvi, true);
return true;
}

return false;
}

private IEnumerable<NavigationViewItem> GetNavigationViewItems()
Expand All @@ -124,7 +98,7 @@ private IEnumerable<NavigationViewItem> GetNavigationViewItems()
new()
{
Content = "Home",
Tag = typeof(MainPage),
Tag = NavigationFactory.GetPages()[0],
IconSource = (IconSource)this.FindResource("HomeIcon")!,
Classes = { "SFPAppNav" }
}
Expand All @@ -138,7 +112,7 @@ private IEnumerable<NavigationViewItem> GetFooterNavigationViewItems()
new()
{
Content = "Settings",
Tag = typeof(SettingsPage),
Tag = NavigationFactory.GetPages()[1],
IconSource = (IconSource)this.FindResource("SettingsIcon")!,
Classes = { "SFPAppNav" }
}
Expand All @@ -147,11 +121,9 @@ private IEnumerable<NavigationViewItem> GetFooterNavigationViewItems()

private void OnNavigationViewItemInvoked(object? sender, NavigationViewItemInvokedEventArgs e)
{
// Change the current selected item back to normal
SetNviIcon((_navView!.SelectedItem as NavigationViewItem)!, false);
if (e.InvokedItemContainer is NavigationViewItem { Tag: Type typ })
if (e.InvokedItemContainer is NavigationViewItem { Tag: Control c })
{
_ = _frameView!.Navigate(typ, null, e.RecommendedNavigationTransitionInfo);
_ = FrameView.NavigateFromObject(c);
}
}
}
2 changes: 1 addition & 1 deletion createpublishedzip.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ function Build-SFP
}
else
{
"--no-self-contained -p:PublishTrimmed=false -p:TrimMode=""full""".Split(" ")
"--no-self-contained"
}
[String[]]$bundleFlag = if ($TargetRuntime.StartsWith("osx") -and $bundle)
{
Expand Down

0 comments on commit d1540a8

Please sign in to comment.