diff --git a/src/Artemis.Core/Artemis.Core.csproj b/src/Artemis.Core/Artemis.Core.csproj index 29ec8c754..86a470004 100644 --- a/src/Artemis.Core/Artemis.Core.csproj +++ b/src/Artemis.Core/Artemis.Core.csproj @@ -12,10 +12,11 @@ x64 + bin\x64\Debug\Artemis.Core.xml - 2.0-{chash:6} + 1.0-{chash:6} true true true @@ -24,8 +25,9 @@ git true - - bin\AnyCPU\Release\Artemis.Core.xml + + + bin\x64\Release\Artemis.Core.xml diff --git a/src/Artemis.Core/Plugins/Modules/ModuleViewModel.cs b/src/Artemis.Core/Plugins/Modules/ModuleViewModel.cs index 0900fb483..df4220793 100644 --- a/src/Artemis.Core/Plugins/Modules/ModuleViewModel.cs +++ b/src/Artemis.Core/Plugins/Modules/ModuleViewModel.cs @@ -15,7 +15,7 @@ namespace Artemis.Core.Plugins.Modules protected ModuleViewModel(Module module, string displayName) { Module = module; - DisplayName = displayName; + DisplayName = displayName.ToUpper(); } /// diff --git a/src/Artemis.Core/Services/CoreService.cs b/src/Artemis.Core/Services/CoreService.cs index e6201f936..030349563 100644 --- a/src/Artemis.Core/Services/CoreService.cs +++ b/src/Artemis.Core/Services/CoreService.cs @@ -176,7 +176,7 @@ namespace Artemis.Core.Services { modules = _modules.Where(m => m.IsActivated || m.InternalExpandsMainDataModel) .OrderBy(m => m.PriorityCategory) - .ThenBy(m => m.Priority) + .ThenByDescending(m => m.Priority) .ToList(); } diff --git a/src/Artemis.Core/Services/ModuleService.cs b/src/Artemis.Core/Services/ModuleService.cs index 812ab5cc9..5cc6cb5e6 100644 --- a/src/Artemis.Core/Services/ModuleService.cs +++ b/src/Artemis.Core/Services/ModuleService.cs @@ -11,6 +11,7 @@ using Artemis.Core.Plugins.Exceptions; using Artemis.Core.Plugins.Modules; using Artemis.Core.Services.Interfaces; using Artemis.Core.Services.Storage.Interfaces; +using Artemis.Storage.Entities.Module; using Artemis.Storage.Repositories.Interfaces; using Serilog; using Timer = System.Timers.Timer; @@ -37,7 +38,8 @@ namespace Artemis.Core.Services activationUpdateTimer.Start(); activationUpdateTimer.Elapsed += ActivationUpdateTimerOnElapsed; - PopulatePriorities(); + foreach (var module in _pluginService.GetPluginsOfType()) + InitialiseOrApplyPriority(module); } public Module ActiveModuleOverride { get; private set; } @@ -123,28 +125,28 @@ namespace Artemis.Core.Services public void UpdateModulePriority(Module module, ModulePriorityCategory category, int priority) { - var modules = _pluginService.GetPluginsOfType().Where(m => m.PriorityCategory == category).OrderBy(m => m.Priority).ToList(); + if (module.PriorityCategory == category && module.Priority == priority) + return; + var modules = _pluginService.GetPluginsOfType().Where(m => m.PriorityCategory == category).OrderBy(m => m.Priority).ToList(); if (modules.Contains(module)) modules.Remove(module); - if (modules.Count == 0) - priority = 0; - else if (priority < 0) - priority = 0; - else if (priority > modules.Count) - priority = modules.Count; - - module.PriorityCategory = category; + priority = Math.Min(modules.Count, Math.Max(0, priority)); modules.Insert(priority, module); + module.PriorityCategory = category; for (var index = 0; index < modules.Count; index++) { var categoryModule = modules[index]; categoryModule.Priority = index; - categoryModule.ApplyToEntity(); - _moduleRepository.Save(categoryModule.Entity); + // Don't save modules whose priority hasn't been initialized yet + if (categoryModule == module || categoryModule.Entity != null) + { + categoryModule.ApplyToEntity(); + _moduleRepository.Save(categoryModule.Entity); + } } } @@ -187,23 +189,6 @@ namespace Artemis.Core.Services } } - private void PopulatePriorities() - { - var modules = _pluginService.GetPluginsOfType().ToList(); - var moduleEntities = _moduleRepository.GetAll(); - - foreach (var module in modules) - { - var entity = moduleEntities.FirstOrDefault(e => e.PluginGuid == module.PluginInfo.Guid); - if (entity != null) - { - module.Entity = entity; - module.PriorityCategory = (ModulePriorityCategory) entity.PriorityCategory; - module.Priority = entity.Priority; - } - } - } - private void PluginServiceOnPluginEnabled(object sender, PluginEventArgs e) { if (e.PluginInfo.Instance is Module module) @@ -212,15 +197,17 @@ namespace Artemis.Core.Services private void InitialiseOrApplyPriority(Module module) { - var entity = _moduleRepository.GetByPluginGuid(module.PluginInfo.Guid); - if (entity != null) + var category = module.DefaultPriorityCategory; + var priority = 1; + + module.Entity = _moduleRepository.GetByPluginGuid(module.PluginInfo.Guid); + if (module.Entity != null) { - module.Entity = entity; - module.PriorityCategory = (ModulePriorityCategory) entity.PriorityCategory; - module.Priority = entity.Priority; + category = (ModulePriorityCategory) module.Entity.PriorityCategory; + priority = module.Entity.Priority; } - else - UpdateModulePriority(module, module.DefaultPriorityCategory, 1); + + UpdateModulePriority(module, category, priority); } } } \ No newline at end of file diff --git a/src/Artemis.Storage/Entities/Module/ModuleSettingsEntity.cs b/src/Artemis.Storage/Entities/Module/ModuleSettingsEntity.cs index 0560635a0..296a5ca8a 100644 --- a/src/Artemis.Storage/Entities/Module/ModuleSettingsEntity.cs +++ b/src/Artemis.Storage/Entities/Module/ModuleSettingsEntity.cs @@ -4,6 +4,12 @@ namespace Artemis.Storage.Entities.Module { public class ModuleSettingsEntity { + public ModuleSettingsEntity() + { + Id = Guid.NewGuid(); + } + + public Guid Id { get; set; } public Guid PluginGuid { get; set; } public int PriorityCategory { get; set; } public int Priority { get; set; } diff --git a/src/Artemis.Storage/Repositories/ModuleRepository.cs b/src/Artemis.Storage/Repositories/ModuleRepository.cs index 9c0c3d51a..6f3ad34b7 100644 --- a/src/Artemis.Storage/Repositories/ModuleRepository.cs +++ b/src/Artemis.Storage/Repositories/ModuleRepository.cs @@ -13,7 +13,7 @@ namespace Artemis.Storage.Repositories internal ModuleRepository(LiteRepository repository) { _repository = repository; - _repository.Database.GetCollection().EnsureIndex(s => s.PluginGuid); + _repository.Database.GetCollection().EnsureIndex(s => s.PluginGuid, true); } public void Add(ModuleSettingsEntity moduleSettingsEntity) diff --git a/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj b/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj index 3170c2590..4f4a56b56 100644 --- a/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj +++ b/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj @@ -15,6 +15,7 @@ x64 + bin\x64\Debug\Artemis.UI.Shared.xml @@ -28,11 +29,8 @@ true 2.0.0 - - bin\AnyCPU\Debug\Artemis.UI.Shared.xml - - - bin\AnyCPU\Release\Artemis.UI.Shared.xml + + bin\x64\Release\Artemis.UI.Shared.xml diff --git a/src/Artemis.UI/Ninject/Factories/IVMFactory.cs b/src/Artemis.UI/Ninject/Factories/IVMFactory.cs index 2433fc64a..597a9c17c 100644 --- a/src/Artemis.UI/Ninject/Factories/IVMFactory.cs +++ b/src/Artemis.UI/Ninject/Factories/IVMFactory.cs @@ -6,8 +6,8 @@ using Artemis.Core.Models.Surface; using Artemis.Core.Plugins; using Artemis.Core.Plugins.Modules; using Artemis.Core.Plugins.Modules.ActivationRequirements; -using Artemis.UI.Screens.Module; -using Artemis.UI.Screens.Module.Tabs; +using Artemis.UI.Screens.Modules; +using Artemis.UI.Screens.Modules.Tabs; using Artemis.UI.Screens.ProfileEditor; using Artemis.UI.Screens.ProfileEditor.DisplayConditions; using Artemis.UI.Screens.ProfileEditor.DisplayConditions.Abstract; diff --git a/src/Artemis.UI/Screens/Module/ModuleRootView.xaml b/src/Artemis.UI/Screens/Modules/ModuleRootView.xaml similarity index 90% rename from src/Artemis.UI/Screens/Module/ModuleRootView.xaml rename to src/Artemis.UI/Screens/Modules/ModuleRootView.xaml index 1b3c50e18..ae7908c5b 100644 --- a/src/Artemis.UI/Screens/Module/ModuleRootView.xaml +++ b/src/Artemis.UI/Screens/Modules/ModuleRootView.xaml @@ -1,10 +1,9 @@ -.Collection.OneActive { private readonly IKernel _kernel; private readonly IModuleVmFactory _moduleVmFactory; - public ModuleRootViewModel(Core.Plugins.Modules.Module module, IModuleVmFactory moduleVmFactory, IKernel kernel) + public ModuleRootViewModel(Module module, IModuleVmFactory moduleVmFactory, IKernel kernel) { DisplayName = module?.DisplayName; Module = module; @@ -22,7 +22,7 @@ namespace Artemis.UI.Screens.Module _kernel = kernel; } - public Core.Plugins.Modules.Module Module { get; } + public Module Module { get; } protected override void OnActivate() { diff --git a/src/Artemis.UI/Screens/Module/Tabs/ActivationRequirementView.xaml b/src/Artemis.UI/Screens/Modules/Tabs/ActivationRequirementView.xaml similarity index 93% rename from src/Artemis.UI/Screens/Module/Tabs/ActivationRequirementView.xaml rename to src/Artemis.UI/Screens/Modules/Tabs/ActivationRequirementView.xaml index 111376651..b0cfae235 100644 --- a/src/Artemis.UI/Screens/Module/Tabs/ActivationRequirementView.xaml +++ b/src/Artemis.UI/Screens/Modules/Tabs/ActivationRequirementView.xaml @@ -1,9 +1,8 @@ - diff --git a/src/Artemis.UI/Screens/Module/Tabs/ActivationRequirementsViewModel.cs b/src/Artemis.UI/Screens/Modules/Tabs/ActivationRequirementsViewModel.cs similarity index 75% rename from src/Artemis.UI/Screens/Module/Tabs/ActivationRequirementsViewModel.cs rename to src/Artemis.UI/Screens/Modules/Tabs/ActivationRequirementsViewModel.cs index 1b49b1a4e..0fe3ff224 100644 --- a/src/Artemis.UI/Screens/Module/Tabs/ActivationRequirementsViewModel.cs +++ b/src/Artemis.UI/Screens/Modules/Tabs/ActivationRequirementsViewModel.cs @@ -3,17 +3,17 @@ using Artemis.Core.Plugins.Modules; using Artemis.UI.Ninject.Factories; using Stylet; -namespace Artemis.UI.Screens.Module.Tabs +namespace Artemis.UI.Screens.Modules.Tabs { public class ActivationRequirementsViewModel : Conductor.Collection.AllActive { private readonly IModuleVmFactory _moduleVmFactory; - public ActivationRequirementsViewModel(Core.Plugins.Modules.Module module, IModuleVmFactory moduleVmFactory) + public ActivationRequirementsViewModel(Module module, IModuleVmFactory moduleVmFactory) { _moduleVmFactory = moduleVmFactory; - DisplayName = "Activation requirements"; + DisplayName = "ACTIVATION REQUIREMENTS"; Module = module; ActivationType = Module.ActivationRequirementMode == ActivationRequirementType.All @@ -21,7 +21,7 @@ namespace Artemis.UI.Screens.Module.Tabs : "any requirement is met"; } - public Core.Plugins.Modules.Module Module { get; } + public Module Module { get; } public string ActivationType { get; set; } diff --git a/src/Artemis.UI/Screens/ProfileEditor/ProfileEditorViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/ProfileEditorViewModel.cs index 4bf212d0f..27a193b66 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/ProfileEditorViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/ProfileEditorViewModel.cs @@ -53,7 +53,7 @@ namespace Artemis.UI.Screens.ProfileEditor _moduleService = moduleService; _snackbarMessageQueue = snackbarMessageQueue; - DisplayName = "Profile editor"; + DisplayName = "PROFILE EDITOR"; Module = module; DialogService = dialogService; @@ -239,6 +239,10 @@ namespace Artemis.UI.Screens.ProfileEditor Module.ActiveProfileChanged += ModuleOnActiveProfileChanged; LoadProfiles(); + // If the module already has an active profile use that, the override won't trigger a profile change + if (Module.ActiveProfile != null) + SelectedProfile = Profiles.FirstOrDefault(d => d.Id == Module.ActiveProfile.EntityId); + Task.Run(async () => { await _moduleService.SetActiveModuleOverride(Module); }); base.OnActivate(); } diff --git a/src/Artemis.UI/Screens/Settings/Tabs/Modules/ModuleOrderModuleView.xaml b/src/Artemis.UI/Screens/Settings/Tabs/Modules/ModuleOrderModuleView.xaml new file mode 100644 index 000000000..c1c633fa9 --- /dev/null +++ b/src/Artemis.UI/Screens/Settings/Tabs/Modules/ModuleOrderModuleView.xaml @@ -0,0 +1,20 @@ + + + + + + + + + + \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Settings/Tabs/Modules/ModuleOrderModuleViewModel.cs b/src/Artemis.UI/Screens/Settings/Tabs/Modules/ModuleOrderModuleViewModel.cs new file mode 100644 index 000000000..392e43dce --- /dev/null +++ b/src/Artemis.UI/Screens/Settings/Tabs/Modules/ModuleOrderModuleViewModel.cs @@ -0,0 +1,43 @@ +using System; +using Artemis.Core.Plugins.Modules; +using Stylet; + +namespace Artemis.UI.Screens.Settings.Tabs.Modules +{ + public class ModuleOrderModuleViewModel : PropertyChangedBase + { + private string _priority; + + public ModuleOrderModuleViewModel(Module module) + { + Module = module; + Update(); + } + + public Module Module { get; } + + public string Priority + { + get => _priority; + set => SetAndNotify(ref _priority, value); + } + + public void Update() + { + switch (Module.PriorityCategory) + { + case ModulePriorityCategory.Normal: + Priority = "3." + (Module.Priority + 1); + break; + case ModulePriorityCategory.Application: + Priority = "2." + (Module.Priority + 1); + break; + case ModulePriorityCategory.Overlay: + Priority = "1." + (Module.Priority + 1); + break; + default: + throw new ArgumentOutOfRangeException(); + } + } + } +} \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Settings/Tabs/Modules/ModuleOrderTabView.xaml b/src/Artemis.UI/Screens/Settings/Tabs/Modules/ModuleOrderTabView.xaml index 6637d78a4..2cf793d66 100644 --- a/src/Artemis.UI/Screens/Settings/Tabs/Modules/ModuleOrderTabView.xaml +++ b/src/Artemis.UI/Screens/Settings/Tabs/Modules/ModuleOrderTabView.xaml @@ -18,14 +18,19 @@ - - + + Drag and drop the modules below to change their rendering priority. + - Like in the profile editor, the modules at the top render over modules at the bottom + - The categories serve as a starting point for new modules, you may freely move modules between the categories + + + - - + + - Overlays + 1 - Overlays - + + + + + + + + + + + + + + + + - + - - + + - Applications/games + 2 - Applications/games - + + + + + + + + + + + + + + + + - + - - + + - Normal + 3 - Normal - + + + + + + + + + + + + + + + + diff --git a/src/Artemis.UI/Screens/Settings/Tabs/Modules/ModuleOrderTabViewModel.cs b/src/Artemis.UI/Screens/Settings/Tabs/Modules/ModuleOrderTabViewModel.cs index 4c707b455..dd2bbe4b0 100644 --- a/src/Artemis.UI/Screens/Settings/Tabs/Modules/ModuleOrderTabViewModel.cs +++ b/src/Artemis.UI/Screens/Settings/Tabs/Modules/ModuleOrderTabViewModel.cs @@ -1,54 +1,84 @@ -using System.Linq; +using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; using Artemis.Core.Plugins.Modules; using Artemis.Core.Services.Interfaces; +using GongSolutions.Wpf.DragDrop; using Stylet; namespace Artemis.UI.Screens.Settings.Tabs.Modules { - public class ModuleOrderTabViewModel : Screen + public class ModuleOrderTabViewModel : Screen, IDropTarget { private readonly IPluginService _pluginService; + private readonly IModuleService _moduleService; + private List _modules; + private DefaultDropHandler _defaultDropHandler; public ModuleOrderTabViewModel(IPluginService pluginService, IModuleService moduleService) { DisplayName = "MODULE PRIORITY"; _pluginService = pluginService; - NormalModules = new BindableCollection(); - ApplicationModules = new BindableCollection(); - OverlayModules = new BindableCollection(); + _moduleService = moduleService; + _modules = new List(pluginService.GetPluginsOfType().Select(m => new ModuleOrderModuleViewModel(m))); + _defaultDropHandler = new DefaultDropHandler(); - ModulesDropHandler = new ModulesDropHandler(moduleService, NormalModules, ApplicationModules, OverlayModules); + NormalModules = new BindableCollection(); + ApplicationModules = new BindableCollection(); + OverlayModules = new BindableCollection(); + + Update(); } - public BindableCollection NormalModules { get; set; } - public BindableCollection ApplicationModules { get; set; } - public BindableCollection OverlayModules { get; set; } + public BindableCollection NormalModules { get; set; } + public BindableCollection ApplicationModules { get; set; } + public BindableCollection OverlayModules { get; set; } - public ModulesDropHandler ModulesDropHandler { get; } - - - protected override void OnActivate() + public void DragOver(IDropInfo dropInfo) { - // Take it off the UI thread to avoid freezing on tab change - Task.Run(() => - { - NormalModules.Clear(); - ApplicationModules.Clear(); - OverlayModules.Clear(); + _defaultDropHandler.DragOver(dropInfo); + } - var instances = _pluginService.GetPluginsOfType().ToList(); - foreach (var module in instances) - { - if (module.PriorityCategory == ModulePriorityCategory.Normal) - NormalModules.Add(module); - else if (module.PriorityCategory == ModulePriorityCategory.Application) - ApplicationModules.Add(module); - else if (module.PriorityCategory == ModulePriorityCategory.Overlay) - OverlayModules.Add(module); - } - }); + public void Drop(IDropInfo dropInfo) + { + if (dropInfo.TargetItem == dropInfo.Data) + return; + + var viewModel = (ModuleOrderModuleViewModel) dropInfo.Data; + var targetCollection = (BindableCollection) dropInfo.TargetCollection; + var insertIndex = dropInfo.InsertIndex; + + ModulePriorityCategory category; + if (targetCollection == NormalModules) + category = ModulePriorityCategory.Normal; + else if (targetCollection == ApplicationModules) + category = ModulePriorityCategory.Application; + else + category = ModulePriorityCategory.Overlay; + + // If moving down, take the removal of ourselves into consideration with the insert index + if (targetCollection.Contains(viewModel) && targetCollection.IndexOf(viewModel) < insertIndex) + insertIndex--; + + _moduleService.UpdateModulePriority(viewModel.Module, category, insertIndex); + + Update(); + } + + public void Update() + { + NormalModules.Clear(); + NormalModules.AddRange(_modules.Where(m => m.Module.PriorityCategory == ModulePriorityCategory.Normal).OrderBy(m => m.Module.Priority)); + + ApplicationModules.Clear(); + ApplicationModules.AddRange(_modules.Where(m => m.Module.PriorityCategory == ModulePriorityCategory.Application).OrderBy(m => m.Module.Priority)); + + OverlayModules.Clear(); + OverlayModules.AddRange(_modules.Where(m => m.Module.PriorityCategory == ModulePriorityCategory.Overlay).OrderBy(m => m.Module.Priority)); + + foreach (var moduleOrderModuleViewModel in _modules) + moduleOrderModuleViewModel.Update(); } } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Settings/Tabs/Modules/ModulesDropHandler.cs b/src/Artemis.UI/Screens/Settings/Tabs/Modules/ModulesDropHandler.cs deleted file mode 100644 index 647eb72ea..000000000 --- a/src/Artemis.UI/Screens/Settings/Tabs/Modules/ModulesDropHandler.cs +++ /dev/null @@ -1,77 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Artemis.Core.Plugins.Modules; -using Artemis.Core.Services.Interfaces; -using GongSolutions.Wpf.DragDrop; -using Stylet; - -namespace Artemis.UI.Screens.Settings.Tabs.Modules -{ - public class ModulesDropHandler : IDropTarget - { - private readonly IModuleService _moduleService; - private readonly BindableCollection _normalModules; - private readonly BindableCollection _applicationModules; - private readonly BindableCollection _overlayModules; - private DefaultDropHandler _defaultDropHandler; - - public ModulesDropHandler(IModuleService moduleService, - BindableCollection normalModules, - BindableCollection applicationModules, - BindableCollection overlayModules) - { - _defaultDropHandler = new DefaultDropHandler(); - _moduleService = moduleService; - _normalModules = normalModules; - _applicationModules = applicationModules; - _overlayModules = overlayModules; - } - - public void DragOver(IDropInfo dropInfo) - { - _defaultDropHandler.DragOver(dropInfo); - } - - public void Drop(IDropInfo dropInfo) - { - var module = (Core.Plugins.Modules.Module) dropInfo.Data; - var target = (BindableCollection) dropInfo.TargetCollection; - var insertIndex = dropInfo.InsertIndex; - - ModulePriorityCategory category; - if (target == _applicationModules) - category = ModulePriorityCategory.Application; - else if (target == _normalModules) - category = ModulePriorityCategory.Normal; - else - category = ModulePriorityCategory.Overlay; - - - if (target.Contains(module)) - { - target.Move(target.IndexOf(module), Math.Min(target.Count - 1, insertIndex)); - _moduleService.UpdateModulePriority(module, category, insertIndex); - } - else - { - if (module.PriorityCategory == ModulePriorityCategory.Application) - _applicationModules.Remove(module); - else if (module.PriorityCategory == ModulePriorityCategory.Normal) - _normalModules.Remove(module); - else if (module.PriorityCategory == ModulePriorityCategory.Overlay) - _overlayModules.Remove(module); - - _moduleService.UpdateModulePriority(module, category, insertIndex); - - if (module.PriorityCategory == ModulePriorityCategory.Application) - _applicationModules.Insert(insertIndex, module); - else if (module.PriorityCategory == ModulePriorityCategory.Normal) - _normalModules.Insert(insertIndex, module); - else if (module.PriorityCategory == ModulePriorityCategory.Overlay) - _overlayModules.Insert(insertIndex, module); - } - } - } -} \ No newline at end of file