diff --git a/SFP_UI/SFP_UI.csproj b/SFP_UI/SFP_UI.csproj index 069ac38..ec72074 100644 --- a/SFP_UI/SFP_UI.csproj +++ b/SFP_UI/SFP_UI.csproj @@ -11,8 +11,6 @@ true true true - - partial true true @@ -28,15 +26,14 @@ - all - - + + diff --git a/SFP_UI/ViewModels/MainViewViewModel.cs b/SFP_UI/ViewModels/MainViewViewModel.cs new file mode 100644 index 0000000..674c5eb --- /dev/null +++ b/SFP_UI/ViewModels/MainViewViewModel.cs @@ -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; + } +} diff --git a/SFP_UI/Views/MainView.axaml.cs b/SFP_UI/Views/MainView.axaml.cs index b12fd20..a6b2f26 100644 --- a/SFP_UI/Views/MainView.axaml.cs +++ b/SFP_UI/Views/MainView.axaml.cs @@ -6,6 +6,7 @@ using FluentAvalonia.UI.Controls; using FluentAvalonia.UI.Navigation; using SFP_UI.Pages; +using SFP_UI.ViewModels; #endregion @@ -13,9 +14,6 @@ namespace SFP_UI.Views; public partial class MainView : UserControl { - private Frame? _frameView; - private NavigationView? _navView; - public MainView() { InitializeComponent(); @@ -25,96 +23,72 @@ protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e) { base.OnAttachedToVisualTree(e); - _frameView = this.FindControl("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("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().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() - .Concat(_navView.FooterMenuItemsSource.Cast()) - .OfType(); - - 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 GetNavigationViewItems() @@ -124,7 +98,7 @@ private IEnumerable GetNavigationViewItems() new() { Content = "Home", - Tag = typeof(MainPage), + Tag = NavigationFactory.GetPages()[0], IconSource = (IconSource)this.FindResource("HomeIcon")!, Classes = { "SFPAppNav" } } @@ -138,7 +112,7 @@ private IEnumerable GetFooterNavigationViewItems() new() { Content = "Settings", - Tag = typeof(SettingsPage), + Tag = NavigationFactory.GetPages()[1], IconSource = (IconSource)this.FindResource("SettingsIcon")!, Classes = { "SFPAppNav" } } @@ -147,11 +121,9 @@ private IEnumerable 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); } } } diff --git a/createpublishedzip.ps1 b/createpublishedzip.ps1 index d66f1c8..d82883f 100644 --- a/createpublishedzip.ps1 +++ b/createpublishedzip.ps1 @@ -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) {