From 827a09ddffa24b04a42cb98cfcf8d83db4625718 Mon Sep 17 00:00:00 2001 From: Chien Zhang Date: Tue, 28 Nov 2023 22:15:58 +0800 Subject: [PATCH] navigation added --- .gitignore | 95 +------------------ .idea/.idea.Chief/.idea/.gitignore | 13 +++ .idea/.idea.Chief/.idea/avalonia.xml | 18 ++++ .idea/.idea.Chief/.idea/indexLayout.xml | 8 ++ .idea/.idea.Chief/.idea/vcs.xml | 6 ++ src/Chief.App/App.axaml | 3 +- src/Chief.App/Chief.App.csproj | 3 +- src/Chief.App/Controls/Card.cs | 10 ++ src/Chief.App/MainWindow.axaml | 39 ++++++-- src/Chief.App/MainWindow.axaml.cs | 58 ++++++++++- src/Chief.App/Models/PageLink.cs | 6 ++ src/Chief.App/Services/NavigationService.cs | 20 +++- .../Styles/ControlThemes/CardStyles.axaml | 13 +++ src/Chief.App/Styles/Controls.axaml | 7 ++ src/Chief.App/ViewModelLocator.cs | 9 +- src/Chief.App/Views/PackageView.axaml | 10 ++ src/Chief.App/Views/PackageView.axaml.cs | 13 +++ src/Chief.App/Views/SettingsView.axaml | 12 +++ src/Chief.App/Views/SettingsView.axaml.cs | 13 +++ src/Chief.App/Views/ToolchainView.axaml | 11 +++ src/Chief.App/Views/ToolchainView.axaml.cs | 13 +++ 21 files changed, 267 insertions(+), 113 deletions(-) create mode 100644 .idea/.idea.Chief/.idea/.gitignore create mode 100644 .idea/.idea.Chief/.idea/avalonia.xml create mode 100644 .idea/.idea.Chief/.idea/indexLayout.xml create mode 100644 .idea/.idea.Chief/.idea/vcs.xml create mode 100644 src/Chief.App/Controls/Card.cs create mode 100644 src/Chief.App/Models/PageLink.cs create mode 100644 src/Chief.App/Styles/ControlThemes/CardStyles.axaml create mode 100644 src/Chief.App/Styles/Controls.axaml create mode 100644 src/Chief.App/Views/PackageView.axaml create mode 100644 src/Chief.App/Views/PackageView.axaml.cs create mode 100644 src/Chief.App/Views/SettingsView.axaml create mode 100644 src/Chief.App/Views/SettingsView.axaml.cs create mode 100644 src/Chief.App/Views/ToolchainView.axaml create mode 100644 src/Chief.App/Views/ToolchainView.axaml.cs diff --git a/.gitignore b/.gitignore index 72c6686..8a30d25 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,3 @@ -# Created by https://www.toptal.com/developers/gitignore/api/visualstudio -# Edit at https://www.toptal.com/developers/gitignore?templates=visualstudio - -### VisualStudio ### ## Ignore Visual Studio temporary files, build results, and ## files generated by popular Visual Studio add-ons. ## @@ -306,6 +302,8 @@ node_modules/ *.dsp # Visual Studio 6 technical files +*.ncb +*.aps # Visual Studio LightSwitch build output **/*.HTMLClient/GeneratedArtifacts @@ -398,92 +396,3 @@ FodyWeavers.xsd # JetBrains Rider *.sln.iml - -### VisualStudio Patch ### -# Additional files built by Visual Studio - -# End of https://www.toptal.com/developers/gitignore/api/visualstudio - -### Rider ### -# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider -# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 - -# User-specific stuff -.idea/**/workspace.xml -.idea/**/tasks.xml -.idea/**/usage.statistics.xml -.idea/**/dictionaries -.idea/**/shelf - -# AWS User-specific -.idea/**/aws.xml - -# Generated files -.idea/**/contentModel.xml - -# Sensitive or high-churn files -.idea/**/dataSources/ -.idea/**/dataSources.ids -.idea/**/dataSources.local.xml -.idea/**/sqlDataSources.xml -.idea/**/dynamic.xml -.idea/**/uiDesigner.xml -.idea/**/dbnavigator.xml - -# Gradle -.idea/**/gradle.xml -.idea/**/libraries - -# Gradle and Maven with auto-import -# When using Gradle or Maven with auto-import, you should exclude module files, -# since they will be recreated, and may cause churn. Uncomment if using -# auto-import. -# .idea/artifacts -# .idea/compiler.xml -# .idea/jarRepositories.xml -# .idea/modules.xml -# .idea/*.iml -# .idea/modules -# *.iml -# *.ipr - -# CMake -cmake-build-*/ - -# Mongo Explorer plugin -.idea/**/mongoSettings.xml - -# File-based project format -*.iws - -# IntelliJ -out/ - -# mpeltonen/sbt-idea plugin -.idea_modules/ - -# JIRA plugin -atlassian-ide-plugin.xml - -# Cursive Clojure plugin -.idea/replstate.xml - -# SonarLint plugin -.idea/sonarlint/ - -# Crashlytics plugin (for Android Studio and IntelliJ) -com_crashlytics_export_strings.xml -crashlytics.properties -crashlytics-build.properties -fabric.properties - -# Editor-based Rest Client -.idea/httpRequests - -# Android studio 3.1+ serialized cache file -.idea/caches/build_file_checksums.ser - -# All rider -.idea/ - -# End of https://www.toptal.com/developers/gitignore/api/rider diff --git a/.idea/.idea.Chief/.idea/.gitignore b/.idea/.idea.Chief/.idea/.gitignore new file mode 100644 index 0000000..5a5a2eb --- /dev/null +++ b/.idea/.idea.Chief/.idea/.gitignore @@ -0,0 +1,13 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Rider ignored files +/projectSettingsUpdater.xml +/modules.xml +/.idea.Chief.iml +/contentModel.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/.idea.Chief/.idea/avalonia.xml b/.idea/.idea.Chief/.idea/avalonia.xml new file mode 100644 index 0000000..3327c55 --- /dev/null +++ b/.idea/.idea.Chief/.idea/avalonia.xml @@ -0,0 +1,18 @@ + + + + + + \ No newline at end of file diff --git a/.idea/.idea.Chief/.idea/indexLayout.xml b/.idea/.idea.Chief/.idea/indexLayout.xml new file mode 100644 index 0000000..7b08163 --- /dev/null +++ b/.idea/.idea.Chief/.idea/indexLayout.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/.idea.Chief/.idea/vcs.xml b/.idea/.idea.Chief/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/.idea.Chief/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/src/Chief.App/App.axaml b/src/Chief.App/App.axaml index c321259..c7173b6 100644 --- a/src/Chief.App/App.axaml +++ b/src/Chief.App/App.axaml @@ -2,12 +2,13 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="Chief.App.App" xmlns:local="using:Chief.App" + xmlns:styles="using:FluentAvalonia.Styling" RequestedThemeVariant="Default"> - + \ No newline at end of file diff --git a/src/Chief.App/Chief.App.csproj b/src/Chief.App/Chief.App.csproj index 4a12998..92b5d0f 100644 --- a/src/Chief.App/Chief.App.csproj +++ b/src/Chief.App/Chief.App.csproj @@ -10,7 +10,6 @@ - @@ -23,6 +22,8 @@ + + diff --git a/src/Chief.App/Controls/Card.cs b/src/Chief.App/Controls/Card.cs new file mode 100644 index 0000000..d4d0b71 --- /dev/null +++ b/src/Chief.App/Controls/Card.cs @@ -0,0 +1,10 @@ +using Avalonia.Controls; + +namespace Chief.App.Controls; + +public class Card: ContentControl +{ + public Card() + { + } +} \ No newline at end of file diff --git a/src/Chief.App/MainWindow.axaml b/src/Chief.App/MainWindow.axaml index 906184d..56ca2bf 100644 --- a/src/Chief.App/MainWindow.axaml +++ b/src/Chief.App/MainWindow.axaml @@ -1,10 +1,29 @@ - - - + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Chief.App/MainWindow.axaml.cs b/src/Chief.App/MainWindow.axaml.cs index 6b01401..88284c7 100644 --- a/src/Chief.App/MainWindow.axaml.cs +++ b/src/Chief.App/MainWindow.axaml.cs @@ -1,13 +1,63 @@ -using Avalonia; -using Avalonia.Controls; -using Avalonia.Markup.Xaml; +using System; +using Avalonia.Interactivity; +using Chief.App.Models; +using Chief.App.Services; +using Chief.App.Views; +using FluentAvalonia.Core; +using FluentAvalonia.UI.Controls; +using FluentAvalonia.UI.Media.Animation; +using FluentAvalonia.UI.Windowing; +using Microsoft.Extensions.DependencyInjection; namespace Chief.App; -public partial class MainWindow : Window +public partial class MainWindow : AppWindow { public MainWindow() { InitializeComponent(); + + // not working in Linux + // TitleBar.ExtendsContentIntoTitleBar = true; + + ViewModelLocator.Instance.Provider.GetRequiredService().RegisterHandler(Navigate); + + var menu = new PageLink[] + { + new("Home", "Home", typeof(HomeView)), + new("Toolchain", "Toolbox", typeof(ToolchainView)), + new("Packages", "Apps", typeof(PackageView)) + }; + var footer = new PageLink[] + { + new("Settings","Settings",typeof(SettingsView)), + }; + Navigation.MenuItemsSource = menu; + Navigation.FooterMenuItemsSource = footer; + Navigation.SelectedItem = Navigation.MenuItemsSource.ElementAt(0); + Navigate(menu[0].Page); + } + + private void Navigate(Type pageType, object? parameter = null, NavigationTransitionInfo? transition = null) + { + if (transition != null) + { + Root.Navigate(pageType, parameter); + } + else if (parameter != null) + { + Root.Navigate(pageType, parameter); + } + else + { + Root.Navigate(pageType); + } + } + + private void Navigation_OnItemInvoked(object? sender, NavigationViewItemInvokedEventArgs e) + { + if (e.InvokedItemContainer.Tag is PageLink link) + ViewModelLocator.Instance.Provider.GetRequiredService() + .Navigate(link.Page, e.RecommendedNavigationTransitionInfo); } } \ No newline at end of file diff --git a/src/Chief.App/Models/PageLink.cs b/src/Chief.App/Models/PageLink.cs new file mode 100644 index 0000000..521c350 --- /dev/null +++ b/src/Chief.App/Models/PageLink.cs @@ -0,0 +1,6 @@ +using System; + +namespace Chief.App.Models; + +// TODO: title 未来替换成 key 用于本地化 +public record PageLink(string Title, string Icon, Type Page); \ No newline at end of file diff --git a/src/Chief.App/Services/NavigationService.cs b/src/Chief.App/Services/NavigationService.cs index 98c176e..9944ede 100644 --- a/src/Chief.App/Services/NavigationService.cs +++ b/src/Chief.App/Services/NavigationService.cs @@ -1,6 +1,24 @@ +using System; +using Avalonia.Controls; +using FluentAvalonia.UI.Media.Animation; + namespace Chief.App.Services; public class NavigationService { - + private Action? navigationHandler; + + public void RegisterHandler(Action handler) + => navigationHandler = handler; + + public void Navigate(NavigationTransitionInfo? transition, object? parameter = null) + where TV : UserControl + =>Navigate(typeof(TV), transition, parameter); + + public void Navigate(object? parameter = null) + where TV : UserControl + => Navigate(null, parameter); + + public void Navigate(Type page, NavigationTransitionInfo? transition, object? parameter = null) + => navigationHandler?.Invoke(page, parameter, transition); } \ No newline at end of file diff --git a/src/Chief.App/Styles/ControlThemes/CardStyles.axaml b/src/Chief.App/Styles/ControlThemes/CardStyles.axaml new file mode 100644 index 0000000..3815a1d --- /dev/null +++ b/src/Chief.App/Styles/ControlThemes/CardStyles.axaml @@ -0,0 +1,13 @@ + + + + + + + + + + + diff --git a/src/Chief.App/Styles/Controls.axaml b/src/Chief.App/Styles/Controls.axaml new file mode 100644 index 0000000..65fb3f3 --- /dev/null +++ b/src/Chief.App/Styles/Controls.axaml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/src/Chief.App/ViewModelLocator.cs b/src/Chief.App/ViewModelLocator.cs index 455d7c8..fe71d5b 100644 --- a/src/Chief.App/ViewModelLocator.cs +++ b/src/Chief.App/ViewModelLocator.cs @@ -7,21 +7,24 @@ namespace Chief.App; public class ViewModelLocator { - public IServiceProvider Provider { get; init; } + public static ViewModelLocator Instance { get; private set; } = null!; + public IServiceProvider Provider { get; } public ViewModelLocator() { Provider = ConfigureServices(); + + Instance = this; } private IServiceProvider ConfigureServices() { var container = new ServiceCollection(); - + container.AddSingleton(); container.AddScoped(); - + return container.BuildServiceProvider(); } diff --git a/src/Chief.App/Views/PackageView.axaml b/src/Chief.App/Views/PackageView.axaml new file mode 100644 index 0000000..50e6438 --- /dev/null +++ b/src/Chief.App/Views/PackageView.axaml @@ -0,0 +1,10 @@ + + + + diff --git a/src/Chief.App/Views/PackageView.axaml.cs b/src/Chief.App/Views/PackageView.axaml.cs new file mode 100644 index 0000000..8aa0e33 --- /dev/null +++ b/src/Chief.App/Views/PackageView.axaml.cs @@ -0,0 +1,13 @@ +using Avalonia; +using Avalonia.Controls; +using Avalonia.Markup.Xaml; + +namespace Chief.App.Views; + +public partial class PackageView : UserControl +{ + public PackageView() + { + InitializeComponent(); + } +} \ No newline at end of file diff --git a/src/Chief.App/Views/SettingsView.axaml b/src/Chief.App/Views/SettingsView.axaml new file mode 100644 index 0000000..2374c32 --- /dev/null +++ b/src/Chief.App/Views/SettingsView.axaml @@ -0,0 +1,12 @@ + + + + + + diff --git a/src/Chief.App/Views/SettingsView.axaml.cs b/src/Chief.App/Views/SettingsView.axaml.cs new file mode 100644 index 0000000..9763f62 --- /dev/null +++ b/src/Chief.App/Views/SettingsView.axaml.cs @@ -0,0 +1,13 @@ +using Avalonia; +using Avalonia.Controls; +using Avalonia.Markup.Xaml; + +namespace Chief.App.Views; + +public partial class SettingsView : UserControl +{ + public SettingsView() + { + InitializeComponent(); + } +} \ No newline at end of file diff --git a/src/Chief.App/Views/ToolchainView.axaml b/src/Chief.App/Views/ToolchainView.axaml new file mode 100644 index 0000000..a10445e --- /dev/null +++ b/src/Chief.App/Views/ToolchainView.axaml @@ -0,0 +1,11 @@ + + + + + + diff --git a/src/Chief.App/Views/ToolchainView.axaml.cs b/src/Chief.App/Views/ToolchainView.axaml.cs new file mode 100644 index 0000000..59c4139 --- /dev/null +++ b/src/Chief.App/Views/ToolchainView.axaml.cs @@ -0,0 +1,13 @@ +using Avalonia; +using Avalonia.Controls; +using Avalonia.Markup.Xaml; + +namespace Chief.App.Views; + +public partial class ToolchainView : UserControl +{ + public ToolchainView() + { + InitializeComponent(); + } +} \ No newline at end of file