vddCore 2 лет назад
Родитель
Сommit
e64dd47921

+ 1 - 0
.idea/.idea.Neptune/.idea/vcs.xml

@@ -2,5 +2,6 @@
 <project version="4">
   <component name="VcsDirectoryMappings">
     <mapping directory="$PROJECT_DIR$" vcs="Git" />
+    <mapping directory="$PROJECT_DIR$/Glitonea" vcs="Git" />
   </component>
 </project>

+ 15 - 0
Neptune/Infrastructure/Services/EditorContextService.cs

@@ -0,0 +1,15 @@
+using Neptune.Model.ProjectManagement;
+
+namespace Neptune.Infrastructure.Services
+{
+    public class EditorContextService : IEditorContextService
+    {
+        private ConfigMember _currentMember;
+        
+        public void UpdateConfigMemberSelection(ConfigMember member) 
+            => _currentMember = member;
+
+        public ConfigMember RetrieveSelectedConfigMember() 
+            => _currentMember;
+    }
+}

+ 11 - 0
Neptune/Infrastructure/Services/IEditorContextService.cs

@@ -0,0 +1,11 @@
+using Glitonea.Mvvm;
+using Neptune.Model.ProjectManagement;
+
+namespace Neptune.Infrastructure.Services
+{
+    public interface IEditorContextService : IService
+    {
+        void UpdateConfigMemberSelection(ConfigMember member);
+        ConfigMember RetrieveSelectedConfigMember();
+    }
+}

+ 1 - 1
Neptune/Infrastructure/Services/RecentProjectService.cs

@@ -27,7 +27,7 @@ namespace Neptune.Infrastructure.Services
                 _appStorage.RecentFiles.Insert(0, projectPath);
             }
 
-            if (_appStorage.RecentFiles.Count > 10)
+            if (_appStorage.RecentFiles.Count > _appStorage.RecentFilesLimit)
             {
                 _appStorage.RecentFiles.RemoveAt(_appStorage.RecentFiles.Count - 1);
             }

+ 3 - 1
Neptune/Model/Storage/AppStorage.cs

@@ -11,6 +11,9 @@ namespace Neptune.Model.Storage
         [JsonIgnore]
         public string FilePath { get; init; }
 
+        [JsonPropertyName("recent_files_limit")]
+        public int RecentFilesLimit { get; set; } = 10;
+
         [JsonPropertyName("recent_files")]
         public ObservableCollection<string> RecentFiles { get; set; } = new();
 
@@ -25,6 +28,5 @@ namespace Neptune.Model.Storage
         {
             FilePath = filePath;
         }
-
     }
 }

+ 7 - 2
Neptune/Neptune.csproj

@@ -27,7 +27,6 @@
     <ItemGroup>
       <Folder Include="Resources\Images\Raster\24" />
       <Folder Include="Resources\Images\Scalable" />
-      <Folder Include="View\Controls\Editors" />
     </ItemGroup>
 
     <ItemGroup>
@@ -41,6 +40,9 @@
       <Compile Update="View\Controls\EditorHost.axaml.cs">
         <DependentUpon>EditorHost.axaml</DependentUpon>
       </Compile>
+      <Compile Update="View\Controls\Editors\XteaKeysEditor.axaml.cs">
+        <DependentUpon>XteaKeysEditorView.axaml</DependentUpon>
+      </Compile>
     </ItemGroup>
 
     <ItemGroup>
@@ -48,7 +50,9 @@
     </ItemGroup>
     
     <ItemGroup>
+      <AvaloniaResource Include="Resources\Images\Raster\16\Bug.png" />
       <AvaloniaResource Include="Resources\Images\Raster\16\Exit.png" />
+      <AvaloniaResource Include="Resources\Images\Raster\16\Help.png" />
       <AvaloniaResource Include="Resources\Images\Raster\16\History.png" />
       <AvaloniaResource Include="Resources\Images\Raster\16\Interface.png" />
       <AvaloniaResource Include="Resources\Images\Raster\16\Key.png" />
@@ -57,6 +61,7 @@
       <AvaloniaResource Include="Resources\Images\Raster\16\OpenFolder.png" />
       <AvaloniaResource Include="Resources\Images\Raster\16\QuestionMark.png" />
       <AvaloniaResource Include="Resources\Images\Raster\16\Save.png" />
+      <AvaloniaResource Include="Resources\Images\Raster\16\Wrench.png" />
         
       <AvaloniaResource Include="Resources\Images\Raster\24\Adventure.png" />
       <AvaloniaResource Include="Resources\Images\Raster\24\ArcherArrow.png" />
@@ -75,6 +80,6 @@
       <AvaloniaResource Include="Resources\Images\Raster\24\PlaceMarker.png" />
       <AvaloniaResource Include="Resources\Images\Raster\24\QuestionMark.png" />
       <AvaloniaResource Include="Resources\Images\Raster\24\Shop.png" />
-      <AvaloniaResource Include="Resources\Images\Raster\24\Unicorn.png" />        
+      <AvaloniaResource Include="Resources\Images\Raster\24\Unicorn.png" />
     </ItemGroup>
 </Project>

+ 3 - 0
Neptune/Resources/Definitions/ImageDefinitions.axaml

@@ -2,7 +2,9 @@
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:sys="clr-namespace:System;assembly=System.Runtime">
     <Styles.Resources>
+        <Image x:Key="NeptuneIconBug_16" Source="avares://Neptune/Resources/Images/Raster/16/Bug.png" />
         <Image x:Key="NeptuneIconExit_16" Source="avares://Neptune/Resources/Images/Raster/16/Exit.png" />
+        <Image x:Key="NeptuneIconHelp_16" Source="avares://Neptune/Resources/Images/Raster/16/Help.png" />
         <Image x:Key="NeptuneIconHistory_16" Source="avares://Neptune/Resources/Images/Raster/16/History.png" />
         <Image x:Key="NeptuneIconInterface_16" Source="avares://Neptune/Resources/Images/Raster/16/Interface.png" />
         <Image x:Key="NeptuneIconKey_16" Source="avares://Neptune/Resources/Images/Raster/16/Key.png" />
@@ -11,6 +13,7 @@
         <Image x:Key="NeptuneIconOpenFolder_16" Source="avares://Neptune/Resources/Images/Raster/16/OpenFolder.png" />
         <Image x:Key="NeptuneIconSave_16" Source="avares://Neptune/Resources/Images/Raster/16/Save.png" />
         <Image x:Key="NeptuneIconQuestionMark_16" Source="avares://Neptune/Resources/Images/Raster/16/QuestionMark.png" />
+        <Image x:Key="NeptuneIconWrench_16" Source="avares://Neptune/Resources/Images/Raster/16/Wrench.png" />
         
         <Image x:Key="NeptuneIconAdventure_24" Source="avares://Neptune/Resources/Images/Raster/24/Adventure.png" />
         <Image x:Key="NeptuneIconArcherArrow_24" Source="avares://Neptune/Resources/Images/Raster/24/ArcherArrow.png" />

BIN
Neptune/Resources/Images/Raster/16/Bug.png


BIN
Neptune/Resources/Images/Raster/16/Help.png


BIN
Neptune/Resources/Images/Raster/16/Wrench.png


+ 56 - 32
Neptune/View/Controls/EditorHost.axaml

@@ -2,40 +2,64 @@
              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
              xmlns:mvvm="clr-namespace:Glitonea.Mvvm;assembly=Glitonea"
              xmlns:vm="clr-namespace:Neptune.ViewModel.Controls"
+             xmlns:vme="clr-namespace:Neptune.ViewModel.Controls.Editors"
+             xmlns:editors="clr-namespace:Neptune.View.Controls.Editors"
+             xmlns:controls="clr-namespace:Neptune.View.Controls"
              x:Class="Neptune.View.Controls.EditorHost"
              DataContext="{mvvm:DataContextSource vm:EditorHostViewModel}">
-    <Grid HorizontalAlignment="Center"
-          VerticalAlignment="Center"
-          ColumnDefinitions="Auto,Auto,Auto"
-          RowDefinitions="Auto,Auto">
-        <TextBlock Grid.Column="0"
-                   Grid.Row="0"
-                   HorizontalAlignment="Center"
-                   FontSize="16"
-                   Text="And here I would display an editor for the "
-                   Opacity="0.4" />
+    <Grid>
+        <ContentPresenter HorizontalAlignment="Stretch"
+                          VerticalAlignment="Stretch"
+                          HorizontalContentAlignment="Stretch"
+                          VerticalContentAlignment="Stretch"
+                          Background="{StaticResource NeptuneDarkBackgroundBrush}"
+                          Content="{Binding $parent[controls:EditorHost].DataContext.CurrentConfigEditor}"
+                          IsVisible="{Binding $parent[controls:EditorHost].DataContext.IsEditorAvailable}">
+            <ContentPresenter.DataTemplates>
+                <DataTemplate DataType="vme:XteaKeysEditorViewModel">
+                    <editors:XteaKeysEditor />
+                </DataTemplate>
 
-        <TextBlock Grid.Column="1"
-                   Grid.Row="0"
-                   HorizontalAlignment="Center"
-                   FontSize="16"
-                   Text="{Binding SelectedConfigMember.FriendlyName}"
-                   Opacity="0.8" />
-        
-        <TextBlock Grid.Column="2"
-                   Grid.Row="0"
-                   HorizontalAlignment="Center"
-                   FontSize="16"
-                   Text="."
-                   Opacity="0.4" />
-        
-        <TextBlock Grid.ColumnSpan="3"
-                   Grid.Row="1"
-                   HorizontalAlignment="Center"
-                   FontSize="16"
-                   Text="IF I HAD ONE"
-                   Foreground="Red"
-                   FontWeight="800"
-                   Opacity="0.8" />
+                <DataTemplate DataType="{x:Null}">
+
+                </DataTemplate>
+            </ContentPresenter.DataTemplates>
+        </ContentPresenter>
+
+        <Grid ColumnDefinitions="Auto,Auto,Auto"
+              RowDefinitions="Auto,Auto"
+              HorizontalAlignment="Center"
+              VerticalAlignment="Center"
+              IsVisible="{Binding !IsEditorAvailable}">
+            <TextBlock Grid.Column="0"
+                       Grid.Row="0"
+                       HorizontalAlignment="Center"
+                       FontSize="16"
+                       Text="And here I would display the editor for "
+                       Opacity="0.4" />
+
+            <TextBlock Grid.Column="1"
+                       Grid.Row="0"
+                       HorizontalAlignment="Center"
+                       FontSize="16"
+                       Text="{Binding SelectedConfigMember.FriendlyName}"
+                       Opacity="0.8" />
+
+            <TextBlock Grid.Column="2"
+                       Grid.Row="0"
+                       HorizontalAlignment="Center"
+                       FontSize="16"
+                       Text="."
+                       Opacity="0.4" />
+
+            <TextBlock Grid.ColumnSpan="3"
+                       Grid.Row="1"
+                       HorizontalAlignment="Center"
+                       FontSize="16"
+                       Text="IF I HAD ONE"
+                       Foreground="Red"
+                       FontWeight="800"
+                       Opacity="0.8" />
+        </Grid>
     </Grid>
 </UserControl>

+ 10 - 0
Neptune/View/Controls/Editors/Base/EditorBase.cs

@@ -0,0 +1,10 @@
+using Avalonia.Controls;
+using PropertyChanged;
+
+namespace Neptune.View.Controls.Editors.Base
+{
+    [DoNotNotify]
+    public abstract class EditorBase : UserControl
+    {
+    }
+}

+ 17 - 0
Neptune/View/Controls/Editors/XteaKeysEditor.axaml

@@ -0,0 +1,17 @@
+<UserControl xmlns="https://github.com/avaloniaui"
+             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+             x:Class="Neptune.View.Controls.Editors.XteaKeysEditor">
+    <StackPanel VerticalAlignment="Center">
+        <TextBlock HorizontalAlignment="Center"
+                   FontSize="16"
+                   Text="I'll be an XTEA key editor soon!" />
+
+        <TextBlock HorizontalAlignment="Center"
+                   FontSize="16"
+                   Text="{Binding Test}" />
+
+        <TextBlock HorizontalAlignment="Center"
+                   FontSize="16"
+                   Text="{Binding ConfigMember.FriendlyName}" />
+    </StackPanel>
+</UserControl>

+ 20 - 0
Neptune/View/Controls/Editors/XteaKeysEditor.axaml.cs

@@ -0,0 +1,20 @@
+using Avalonia.Markup.Xaml;
+using Neptune.View.Controls.Editors.Base;
+using PropertyChanged;
+
+namespace Neptune.View.Controls.Editors
+{
+    [DoNotNotify]
+    public partial class XteaKeysEditor : EditorBase
+    {
+        public XteaKeysEditor()
+        {
+            InitializeComponent();
+        }
+
+        private void InitializeComponent()
+        {
+            AvaloniaXamlLoader.Load(this);
+        }
+    }
+}

+ 29 - 11
Neptune/View/Windows/MainWindow.axaml

@@ -28,9 +28,7 @@
                           Command="{Binding LoadProject}"
                           CommandParameter="{Binding #RecentsMenuItem.Selection.SelectedItem}"
                           IsEnabled="{Binding !!RecentProjects.Count}"
-                          Icon="{StaticResource NeptuneIconHistory_16}"
-                          InputGesture="Ctrl+R"
-                          HotKey="Ctrl+R" />
+                          Icon="{StaticResource NeptuneIconHistory_16}" />
 
                 <MenuItem Header="_Save"
                           Command="{Binding SaveCurrentProject}"
@@ -54,16 +52,36 @@
                           HotKey="Ctrl+Q" />
             </MenuItem>
 
-            <MenuItem Header="Edit" />
-            <MenuItem Header="View" />
+            <MenuItem Header="_Edit">
+                <MenuItem Header="_Preferences" 
+                          Command="{Binding OpenSettingsWindow}"
+                          Icon="{StaticResource NeptuneIconWrench_16}"
+                          InputGesture="Ctrl+K"
+                          HotKey="Ctrl+K" />
+            </MenuItem>
             
-            <MenuItem Header="Help">
-                <MenuItem Header="Documentation" />
-                <MenuItem Header="Report a bug" />
+            <MenuItem Header="View" />
+
+            <MenuItem Header="_Help">
+                <MenuItem Header="_Documentation" 
+                          Command="{Binding OpenDocumentation}" 
+                          Icon="{StaticResource NeptuneIconHelp_16}"
+                          InputGesture="Ctrl+F12"
+                          HotKey="Ctrl+F12" />
                 
+                <MenuItem Header="Report a _bug" 
+                          Command="{Binding OpenIssuesPage}" 
+                          Icon="{StaticResource NeptuneIconBug_16}"
+                          InputGesture="Ctrl+F11"
+                          HotKey="Ctrl+F11" />
+
                 <Separator />
-                
-                <MenuItem Header="About this program" />
+
+                <MenuItem Header="_About this program"
+                          Command="{Binding OpenAboutWindow}"
+                          Icon="{StaticResource NeptuneIconQuestionMark_16}"
+                          InputGesture="Ctrl+F10"
+                          HotKey="Ctrl+F10" />
             </MenuItem>
         </Menu>
 
@@ -117,7 +135,7 @@
                     </DataTriggerBehavior>
                 </Interaction.Behaviors>
 
-                <controls:EditorHost IsVisible="{Binding !!SelectedConfigMember}" />
+                <controls:EditorHost IsVisible="{Binding $parent[view:MainWindow].DataContext.IsConfigMemberSelected}" />
             </Grid>
 
             <Grid VerticalAlignment="Center"

+ 55 - 1
Neptune/ViewModel/Controls/EditorHostViewModel.cs

@@ -1,22 +1,76 @@
+using System;
+using System.Collections.Generic;
 using Glitonea.Mvvm;
 using Glitonea.Mvvm.Messaging;
 using Neptune.Infrastructure.Messaging;
+using Neptune.Infrastructure.Services;
 using Neptune.Model.ProjectManagement;
+using Neptune.ViewModel.Controls.Editors;
+using Neptune.ViewModel.Controls.Editors.Base;
 
 namespace Neptune.ViewModel.Controls
 {
     public class EditorHostViewModel : ViewModelBase
     {
+        private readonly Dictionary<ConfigMemberType, Func<ViewModelBase>> _configViewModelMap = new()
+        {
+            { ConfigMemberType.XteaKeys, ViewModelResolver.Instance.Resolve<XteaKeysEditorViewModel> }
+        };
+        
+        private readonly IEditorContextService _editorContextService;
+
+        private EditorViewModelBase _currentConfigEditor;
+        
+        public bool IsEditorAvailable => CurrentConfigEditor != null;
+        
         public ConfigMember SelectedConfigMember { get; private set; }
 
-        public EditorHostViewModel()
+        public EditorViewModelBase CurrentConfigEditor
+        {
+            get => _currentConfigEditor;
+
+            set
+            {
+                _currentConfigEditor = value;
+                OnPropertyChanged(nameof(CurrentConfigEditor));
+                OnPropertyChanged(nameof(IsEditorAvailable));
+            }
+        }
+        
+        public EditorHostViewModel(IEditorContextService editorContextService)
         {
+            _editorContextService = editorContextService;
+            
             Message.Subscribe<SelectedConfigMemberChangedMessage>(this, SelectedConfigMemberChanged);
         }
 
         private void SelectedConfigMemberChanged(SelectedConfigMemberChangedMessage msg)
         {
             SelectedConfigMember = msg.ConfigMember;
+            _editorContextService.UpdateConfigMemberSelection(SelectedConfigMember);
+            
+            if (CurrentConfigEditor != null)
+            {
+                CurrentConfigEditor.OnDeactivated();
+            }
+            
+            CurrentConfigEditor = ResolveConfigEditor();
+
+            if (CurrentConfigEditor != null)
+            {   
+                CurrentConfigEditor.OnActivated();
+            }
+        }
+
+        private EditorViewModelBase ResolveConfigEditor()
+        {
+            if (SelectedConfigMember == null)
+                return null;
+
+            if (!_configViewModelMap.ContainsKey(SelectedConfigMember.Type))
+                return null;
+            
+            return _configViewModelMap[SelectedConfigMember.Type]() as EditorViewModelBase;
         }
     }
 }

+ 27 - 0
Neptune/ViewModel/Controls/Editors/Base/EditorViewModelBase.cs

@@ -0,0 +1,27 @@
+using Glitonea.Mvvm;
+using Neptune.Infrastructure.Services;
+using Neptune.Model.ProjectManagement;
+
+namespace Neptune.ViewModel.Controls.Editors.Base
+{
+    public abstract class EditorViewModelBase : ViewModelBase
+    {
+        protected readonly IEditorContextService _editorContextService;
+        
+        public ConfigMember ConfigMember { get; protected set; }
+
+        public EditorViewModelBase(IEditorContextService editorContextService)
+        {
+            _editorContextService = editorContextService;
+        }
+
+        public virtual void OnActivated()
+        {
+            ConfigMember = _editorContextService.RetrieveSelectedConfigMember();
+        }
+
+        public virtual void OnDeactivated()
+        {
+        }
+    }
+}

+ 15 - 0
Neptune/ViewModel/Controls/Editors/XteaKeysEditorViewModel.cs

@@ -0,0 +1,15 @@
+using Neptune.Infrastructure.Services;
+using Neptune.ViewModel.Controls.Editors.Base;
+
+namespace Neptune.ViewModel.Controls.Editors
+{
+    public class XteaKeysEditorViewModel : EditorViewModelBase
+    {
+        public string Test { get; set; } = "lorem ipsum dolor sit amet";
+        
+        public XteaKeysEditorViewModel(IEditorContextService editorContextService)
+            : base(editorContextService)
+        {
+        }
+    }
+}

+ 17 - 2
Neptune/ViewModel/Windows/MainWindowViewModel.cs

@@ -21,6 +21,7 @@ namespace Neptune.ViewModel.Windows
 
         private AppStorage _appStorage;
         private Project _project;
+        private ConfigMember _selectedConfigMember;
 
         public GridLength GridSplitterPosition
         {
@@ -28,7 +29,6 @@ namespace Neptune.ViewModel.Windows
             set => _appStorage.GridSplitterPosition = value.Value;
         }
 
-        public bool IsProjectLoaded => Project != null;
         public ObservableCollection<string> RecentProjects { get; private set; }
         
         public Project Project
@@ -44,7 +44,22 @@ namespace Neptune.ViewModel.Windows
             }
         }
 
-        public ConfigMember SelectedConfigMember { get; private set; }
+        
+        public ConfigMember SelectedConfigMember
+        {
+            get => _selectedConfigMember;
+
+            set
+            {
+                _selectedConfigMember = value;
+
+                OnPropertyChanged(nameof(SelectedConfigMember));
+                OnPropertyChanged(nameof(IsConfigMemberSelected));
+            }
+        }
+        
+        public bool IsProjectLoaded => Project != null;
+        public bool IsConfigMemberSelected => SelectedConfigMember != null;
 
         public MainWindowViewModel(
             IProjectService projectService,