1
0
mirror of https://github.com/Artemis-RGB/Artemis synced 2025-12-13 05:48:35 +00:00

UI - Made module tabs uppercase since that's what we do

Modules - Finished module ordering
This commit is contained in:
Robert 2020-08-27 19:47:27 +02:00
parent bfb122e95a
commit babd862b40
20 changed files with 272 additions and 208 deletions

View File

@ -12,10 +12,11 @@
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<PlatformTarget>x64</PlatformTarget> <PlatformTarget>x64</PlatformTarget>
<DocumentationFile>bin\x64\Debug\Artemis.Core.xml</DocumentationFile>
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>
<NrtRevisionFormat>2.0-{chash:6}</NrtRevisionFormat> <NrtRevisionFormat>1.0-{chash:6}</NrtRevisionFormat>
<NrtResolveSimpleAttributes>true</NrtResolveSimpleAttributes> <NrtResolveSimpleAttributes>true</NrtResolveSimpleAttributes>
<NrtResolveInformationalAttribute>true</NrtResolveInformationalAttribute> <NrtResolveInformationalAttribute>true</NrtResolveInformationalAttribute>
<NrtResolveCopyright>true</NrtResolveCopyright> <NrtResolveCopyright>true</NrtResolveCopyright>
@ -24,8 +25,9 @@
<NrtRequiredVcs>git</NrtRequiredVcs> <NrtRequiredVcs>git</NrtRequiredVcs>
<NrtShowRevision>true</NrtShowRevision> <NrtShowRevision>true</NrtShowRevision>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<DocumentationFile>bin\AnyCPU\Release\Artemis.Core.xml</DocumentationFile> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<DocumentationFile>bin\x64\Release\Artemis.Core.xml</DocumentationFile>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Artemis.Storage\Artemis.Storage.csproj"> <ProjectReference Include="..\Artemis.Storage\Artemis.Storage.csproj">

View File

@ -15,7 +15,7 @@ namespace Artemis.Core.Plugins.Modules
protected ModuleViewModel(Module module, string displayName) protected ModuleViewModel(Module module, string displayName)
{ {
Module = module; Module = module;
DisplayName = displayName; DisplayName = displayName.ToUpper();
} }
/// <summary> /// <summary>

View File

@ -176,7 +176,7 @@ namespace Artemis.Core.Services
{ {
modules = _modules.Where(m => m.IsActivated || m.InternalExpandsMainDataModel) modules = _modules.Where(m => m.IsActivated || m.InternalExpandsMainDataModel)
.OrderBy(m => m.PriorityCategory) .OrderBy(m => m.PriorityCategory)
.ThenBy(m => m.Priority) .ThenByDescending(m => m.Priority)
.ToList(); .ToList();
} }

View File

@ -11,6 +11,7 @@ using Artemis.Core.Plugins.Exceptions;
using Artemis.Core.Plugins.Modules; using Artemis.Core.Plugins.Modules;
using Artemis.Core.Services.Interfaces; using Artemis.Core.Services.Interfaces;
using Artemis.Core.Services.Storage.Interfaces; using Artemis.Core.Services.Storage.Interfaces;
using Artemis.Storage.Entities.Module;
using Artemis.Storage.Repositories.Interfaces; using Artemis.Storage.Repositories.Interfaces;
using Serilog; using Serilog;
using Timer = System.Timers.Timer; using Timer = System.Timers.Timer;
@ -37,7 +38,8 @@ namespace Artemis.Core.Services
activationUpdateTimer.Start(); activationUpdateTimer.Start();
activationUpdateTimer.Elapsed += ActivationUpdateTimerOnElapsed; activationUpdateTimer.Elapsed += ActivationUpdateTimerOnElapsed;
PopulatePriorities(); foreach (var module in _pluginService.GetPluginsOfType<Module>())
InitialiseOrApplyPriority(module);
} }
public Module ActiveModuleOverride { get; private set; } public Module ActiveModuleOverride { get; private set; }
@ -123,28 +125,28 @@ namespace Artemis.Core.Services
public void UpdateModulePriority(Module module, ModulePriorityCategory category, int priority) public void UpdateModulePriority(Module module, ModulePriorityCategory category, int priority)
{ {
var modules = _pluginService.GetPluginsOfType<Module>().Where(m => m.PriorityCategory == category).OrderBy(m => m.Priority).ToList(); if (module.PriorityCategory == category && module.Priority == priority)
return;
var modules = _pluginService.GetPluginsOfType<Module>().Where(m => m.PriorityCategory == category).OrderBy(m => m.Priority).ToList();
if (modules.Contains(module)) if (modules.Contains(module))
modules.Remove(module); modules.Remove(module);
if (modules.Count == 0) priority = Math.Min(modules.Count, Math.Max(0, priority));
priority = 0;
else if (priority < 0)
priority = 0;
else if (priority > modules.Count)
priority = modules.Count;
module.PriorityCategory = category;
modules.Insert(priority, module); modules.Insert(priority, module);
module.PriorityCategory = category;
for (var index = 0; index < modules.Count; index++) for (var index = 0; index < modules.Count; index++)
{ {
var categoryModule = modules[index]; var categoryModule = modules[index];
categoryModule.Priority = 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<Module>().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) private void PluginServiceOnPluginEnabled(object sender, PluginEventArgs e)
{ {
if (e.PluginInfo.Instance is Module module) if (e.PluginInfo.Instance is Module module)
@ -212,15 +197,17 @@ namespace Artemis.Core.Services
private void InitialiseOrApplyPriority(Module module) private void InitialiseOrApplyPriority(Module module)
{ {
var entity = _moduleRepository.GetByPluginGuid(module.PluginInfo.Guid); var category = module.DefaultPriorityCategory;
if (entity != null) var priority = 1;
module.Entity = _moduleRepository.GetByPluginGuid(module.PluginInfo.Guid);
if (module.Entity != null)
{ {
module.Entity = entity; category = (ModulePriorityCategory) module.Entity.PriorityCategory;
module.PriorityCategory = (ModulePriorityCategory) entity.PriorityCategory; priority = module.Entity.Priority;
module.Priority = entity.Priority;
} }
else
UpdateModulePriority(module, module.DefaultPriorityCategory, 1); UpdateModulePriority(module, category, priority);
} }
} }
} }

View File

@ -4,6 +4,12 @@ namespace Artemis.Storage.Entities.Module
{ {
public class ModuleSettingsEntity public class ModuleSettingsEntity
{ {
public ModuleSettingsEntity()
{
Id = Guid.NewGuid();
}
public Guid Id { get; set; }
public Guid PluginGuid { get; set; } public Guid PluginGuid { get; set; }
public int PriorityCategory { get; set; } public int PriorityCategory { get; set; }
public int Priority { get; set; } public int Priority { get; set; }

View File

@ -13,7 +13,7 @@ namespace Artemis.Storage.Repositories
internal ModuleRepository(LiteRepository repository) internal ModuleRepository(LiteRepository repository)
{ {
_repository = repository; _repository = repository;
_repository.Database.GetCollection<ModuleSettingsEntity>().EnsureIndex(s => s.PluginGuid); _repository.Database.GetCollection<ModuleSettingsEntity>().EnsureIndex(s => s.PluginGuid, true);
} }
public void Add(ModuleSettingsEntity moduleSettingsEntity) public void Add(ModuleSettingsEntity moduleSettingsEntity)

View File

@ -15,6 +15,7 @@
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<PlatformTarget>x64</PlatformTarget> <PlatformTarget>x64</PlatformTarget>
<DocumentationFile>bin\x64\Debug\Artemis.UI.Shared.xml</DocumentationFile>
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>
@ -28,11 +29,8 @@
<NrtShowRevision>true</NrtShowRevision> <NrtShowRevision>true</NrtShowRevision>
<Version>2.0.0</Version> <Version>2.0.0</Version>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<DocumentationFile>bin\AnyCPU\Debug\Artemis.UI.Shared.xml</DocumentationFile> <DocumentationFile>bin\x64\Release\Artemis.UI.Shared.xml</DocumentationFile>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<DocumentationFile>bin\AnyCPU\Release\Artemis.UI.Shared.xml</DocumentationFile>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="AvalonEdit" Version="6.0.1" /> <PackageReference Include="AvalonEdit" Version="6.0.1" />

View File

@ -6,8 +6,8 @@ using Artemis.Core.Models.Surface;
using Artemis.Core.Plugins; using Artemis.Core.Plugins;
using Artemis.Core.Plugins.Modules; using Artemis.Core.Plugins.Modules;
using Artemis.Core.Plugins.Modules.ActivationRequirements; using Artemis.Core.Plugins.Modules.ActivationRequirements;
using Artemis.UI.Screens.Module; using Artemis.UI.Screens.Modules;
using Artemis.UI.Screens.Module.Tabs; using Artemis.UI.Screens.Modules.Tabs;
using Artemis.UI.Screens.ProfileEditor; using Artemis.UI.Screens.ProfileEditor;
using Artemis.UI.Screens.ProfileEditor.DisplayConditions; using Artemis.UI.Screens.ProfileEditor.DisplayConditions;
using Artemis.UI.Screens.ProfileEditor.DisplayConditions.Abstract; using Artemis.UI.Screens.ProfileEditor.DisplayConditions.Abstract;

View File

@ -1,10 +1,9 @@
<UserControl x:Class="Artemis.UI.Screens.Module.ModuleRootView" <UserControl x:Class="Artemis.UI.Screens.Modules.ModuleRootView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:s="https://github.com/canton7/Stylet" xmlns:s="https://github.com/canton7/Stylet"
xmlns:module="clr-namespace:Artemis.UI.Screens.Module"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
mc:Ignorable="d" mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800" d:DesignHeight="450" d:DesignWidth="800"

View File

@ -6,14 +6,14 @@ using Ninject;
using Ninject.Parameters; using Ninject.Parameters;
using Stylet; using Stylet;
namespace Artemis.UI.Screens.Module namespace Artemis.UI.Screens.Modules
{ {
public class ModuleRootViewModel : Conductor<Screen>.Collection.OneActive public class ModuleRootViewModel : Conductor<Screen>.Collection.OneActive
{ {
private readonly IKernel _kernel; private readonly IKernel _kernel;
private readonly IModuleVmFactory _moduleVmFactory; 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; DisplayName = module?.DisplayName;
Module = module; Module = module;
@ -22,7 +22,7 @@ namespace Artemis.UI.Screens.Module
_kernel = kernel; _kernel = kernel;
} }
public Core.Plugins.Modules.Module Module { get; } public Module Module { get; }
protected override void OnActivate() protected override void OnActivate()
{ {

View File

@ -1,9 +1,8 @@
<UserControl x:Class="Artemis.UI.Screens.Module.Tabs.ActivationRequirementView" <UserControl x:Class="Artemis.UI.Screens.Modules.Tabs.ActivationRequirementView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Artemis.UI.Screens.Module.Tabs"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
mc:Ignorable="d" mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800" d:DesignHeight="450" d:DesignWidth="800"

View File

@ -3,7 +3,7 @@ using Artemis.Core.Plugins.Modules.ActivationRequirements;
using Humanizer; using Humanizer;
using Stylet; using Stylet;
namespace Artemis.UI.Screens.Module.Tabs namespace Artemis.UI.Screens.Modules.Tabs
{ {
public class ActivationRequirementViewModel : Screen public class ActivationRequirementViewModel : Screen
{ {

View File

@ -1,11 +1,11 @@
<UserControl x:Class="Artemis.UI.Screens.Module.Tabs.ActivationRequirementsView" <UserControl x:Class="Artemis.UI.Screens.Modules.Tabs.ActivationRequirementsView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Artemis.UI.Screens.Module.Tabs"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:s="https://github.com/canton7/Stylet" xmlns:s="https://github.com/canton7/Stylet"
xmlns:local="clr-namespace:Artemis.UI.Screens.Modules.Tabs"
mc:Ignorable="d" mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800" d:DesignHeight="450" d:DesignWidth="800"
d:DataContext="{d:DesignInstance local:ActivationRequirementsViewModel}"> d:DataContext="{d:DesignInstance local:ActivationRequirementsViewModel}">

View File

@ -3,17 +3,17 @@ using Artemis.Core.Plugins.Modules;
using Artemis.UI.Ninject.Factories; using Artemis.UI.Ninject.Factories;
using Stylet; using Stylet;
namespace Artemis.UI.Screens.Module.Tabs namespace Artemis.UI.Screens.Modules.Tabs
{ {
public class ActivationRequirementsViewModel : Conductor<ActivationRequirementViewModel>.Collection.AllActive public class ActivationRequirementsViewModel : Conductor<ActivationRequirementViewModel>.Collection.AllActive
{ {
private readonly IModuleVmFactory _moduleVmFactory; private readonly IModuleVmFactory _moduleVmFactory;
public ActivationRequirementsViewModel(Core.Plugins.Modules.Module module, IModuleVmFactory moduleVmFactory) public ActivationRequirementsViewModel(Module module, IModuleVmFactory moduleVmFactory)
{ {
_moduleVmFactory = moduleVmFactory; _moduleVmFactory = moduleVmFactory;
DisplayName = "Activation requirements"; DisplayName = "ACTIVATION REQUIREMENTS";
Module = module; Module = module;
ActivationType = Module.ActivationRequirementMode == ActivationRequirementType.All ActivationType = Module.ActivationRequirementMode == ActivationRequirementType.All
@ -21,7 +21,7 @@ namespace Artemis.UI.Screens.Module.Tabs
: "any requirement is met"; : "any requirement is met";
} }
public Core.Plugins.Modules.Module Module { get; } public Module Module { get; }
public string ActivationType { get; set; } public string ActivationType { get; set; }

View File

@ -53,7 +53,7 @@ namespace Artemis.UI.Screens.ProfileEditor
_moduleService = moduleService; _moduleService = moduleService;
_snackbarMessageQueue = snackbarMessageQueue; _snackbarMessageQueue = snackbarMessageQueue;
DisplayName = "Profile editor"; DisplayName = "PROFILE EDITOR";
Module = module; Module = module;
DialogService = dialogService; DialogService = dialogService;
@ -239,6 +239,10 @@ namespace Artemis.UI.Screens.ProfileEditor
Module.ActiveProfileChanged += ModuleOnActiveProfileChanged; Module.ActiveProfileChanged += ModuleOnActiveProfileChanged;
LoadProfiles(); 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); }); Task.Run(async () => { await _moduleService.SetActiveModuleOverride(Module); });
base.OnActivate(); base.OnActivate();
} }

View File

@ -0,0 +1,20 @@
<UserControl x:Class="Artemis.UI.Screens.Settings.Tabs.Modules.ModuleOrderModuleView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Artemis.UI.Screens.Settings.Tabs.Modules"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
d:DataContext="{d:DesignInstance local:ModuleOrderModuleViewModel}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="40"/>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Priority}"
Style="{StaticResource MaterialDesignTextBlock}"
Foreground="{DynamicResource MaterialDesignNavigationItemSubheader}" />
<TextBlock Grid.Column="1" Text="{Binding Module.DisplayName}" Style="{StaticResource MaterialDesignTextBlock}" />
</Grid>
</UserControl>

View File

@ -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();
}
}
}
}

View File

@ -18,14 +18,19 @@
<RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/>
</Grid.RowDefinitions> </Grid.RowDefinitions>
<!-- Profile editor settings -->
<StackPanel> <StackPanel>
<Grid Margin="0 15"> <TextBlock TextWrapping="Wrap" Style="{StaticResource MaterialDesignTextBlock}">
Drag and drop the modules below to change their rendering priority. <LineBreak/><LineBreak/>
- Like in the profile editor, the modules at the top render over modules at the bottom <LineBreak/>
- The categories serve as a starting point for new modules, you may freely move modules between the categories <LineBreak/>
</TextBlock>
<Grid Margin="0 0 0 5">
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition /> <ColumnDefinition Width="Auto"/>
<ColumnDefinition /> <ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<TextBlock Style="{StaticResource MaterialDesignHeadline5TextBlock}">Overlays</TextBlock> <TextBlock Style="{StaticResource MaterialDesignHeadline5TextBlock}">1 - Overlays</TextBlock>
<TextBlock Grid.Column="1" <TextBlock Grid.Column="1"
Style="{StaticResource MaterialDesignCaptionTextBlock}" Style="{StaticResource MaterialDesignCaptionTextBlock}"
VerticalAlignment="Bottom" VerticalAlignment="Bottom"
@ -36,25 +41,41 @@
</Grid> </Grid>
<materialDesign:Card materialDesign:ShadowAssist.ShadowDepth="Depth1" VerticalAlignment="Stretch" Margin="0,0,5,0"> <materialDesign:Card materialDesign:ShadowAssist.ShadowDepth="Depth1" VerticalAlignment="Stretch" Margin="0,0,5,0">
<StackPanel Margin="15"> <StackPanel Margin="15">
<ListBox ItemsSource="{Binding OverlayModules}" <Border BorderThickness="2" >
DisplayMemberPath="DisplayName" <Border.BorderBrush>
materialDesign:RippleAssist.IsDisabled="True" <VisualBrush>
dd:DragDrop.IsDragSource="True" <VisualBrush.Visual>
dd:DragDrop.IsDropTarget="True" <Rectangle StrokeDashArray="4 2" Stroke="{DynamicResource MaterialDesignDivider}" StrokeThickness="2"
dd:DragDrop.UseDefaultDragAdorner="True" Width="{Binding RelativeSource={RelativeSource AncestorType={x:Type Border}}, Path=ActualWidth}"
dd:DragDrop.DropHandler="{Binding ModulesDropHandler}" Height="{Binding RelativeSource={RelativeSource AncestorType={x:Type Border}}, Path=ActualHeight}"/>
MinHeight="30"/> </VisualBrush.Visual>
</VisualBrush>
</Border.BorderBrush>
<ListBox ItemsSource="{Binding OverlayModules}"
materialDesign:RippleAssist.IsDisabled="True"
dd:DragDrop.IsDragSource="True"
dd:DragDrop.IsDropTarget="True"
dd:DragDrop.UseDefaultDragAdorner="True"
dd:DragDrop.DropHandler="{Binding}"
MinHeight="40">
<ListBox.ItemTemplate>
<DataTemplate>
<ContentControl s:View.Model="{Binding}" VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch" IsTabStop="False"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Border>
</StackPanel> </StackPanel>
</materialDesign:Card> </materialDesign:Card>
</StackPanel> </StackPanel>
<StackPanel Grid.Row="1"> <StackPanel Grid.Row="1">
<Grid Margin="0 15"> <Grid Margin="0 15 0 5">
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition /> <ColumnDefinition Width="Auto"/>
<ColumnDefinition /> <ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<TextBlock Style="{StaticResource MaterialDesignHeadline5TextBlock}">Applications/games</TextBlock> <TextBlock Style="{StaticResource MaterialDesignHeadline5TextBlock}">2 - Applications/games</TextBlock>
<TextBlock Grid.Column="1" <TextBlock Grid.Column="1"
Style="{StaticResource MaterialDesignCaptionTextBlock}" Style="{StaticResource MaterialDesignCaptionTextBlock}"
VerticalAlignment="Bottom" VerticalAlignment="Bottom"
@ -65,25 +86,41 @@
</Grid> </Grid>
<materialDesign:Card materialDesign:ShadowAssist.ShadowDepth="Depth1" VerticalAlignment="Stretch" Margin="0,0,5,0"> <materialDesign:Card materialDesign:ShadowAssist.ShadowDepth="Depth1" VerticalAlignment="Stretch" Margin="0,0,5,0">
<StackPanel Margin="15"> <StackPanel Margin="15">
<ListBox ItemsSource="{Binding ApplicationModules}" <Border BorderThickness="2" >
DisplayMemberPath="DisplayName" <Border.BorderBrush>
materialDesign:RippleAssist.IsDisabled="True" <VisualBrush>
dd:DragDrop.IsDragSource="True" <VisualBrush.Visual>
dd:DragDrop.IsDropTarget="True" <Rectangle StrokeDashArray="4 2" Stroke="{DynamicResource MaterialDesignDivider}" StrokeThickness="2"
dd:DragDrop.UseDefaultDragAdorner="True" Width="{Binding RelativeSource={RelativeSource AncestorType={x:Type Border}}, Path=ActualWidth}"
dd:DragDrop.DropHandler="{Binding ModulesDropHandler}" Height="{Binding RelativeSource={RelativeSource AncestorType={x:Type Border}}, Path=ActualHeight}"/>
MinHeight="30"/> </VisualBrush.Visual>
</VisualBrush>
</Border.BorderBrush>
<ListBox ItemsSource="{Binding ApplicationModules}"
materialDesign:RippleAssist.IsDisabled="True"
dd:DragDrop.IsDragSource="True"
dd:DragDrop.IsDropTarget="True"
dd:DragDrop.UseDefaultDragAdorner="True"
dd:DragDrop.DropHandler="{Binding}"
MinHeight="40">
<ListBox.ItemTemplate>
<DataTemplate>
<ContentControl s:View.Model="{Binding}" VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch" IsTabStop="False"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Border>
</StackPanel> </StackPanel>
</materialDesign:Card> </materialDesign:Card>
</StackPanel> </StackPanel>
<StackPanel Grid.Row="2"> <StackPanel Grid.Row="2">
<Grid Margin="0 15"> <Grid Margin="0 15 0 5">
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition /> <ColumnDefinition Width="Auto"/>
<ColumnDefinition /> <ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<TextBlock Style="{StaticResource MaterialDesignHeadline5TextBlock}">Normal</TextBlock> <TextBlock Style="{StaticResource MaterialDesignHeadline5TextBlock}">3 - Normal</TextBlock>
<TextBlock Grid.Column="1" <TextBlock Grid.Column="1"
Style="{StaticResource MaterialDesignCaptionTextBlock}" Style="{StaticResource MaterialDesignCaptionTextBlock}"
VerticalAlignment="Bottom" VerticalAlignment="Bottom"
@ -94,14 +131,30 @@
</Grid> </Grid>
<materialDesign:Card materialDesign:ShadowAssist.ShadowDepth="Depth1" VerticalAlignment="Stretch" Margin="0,0,5,0"> <materialDesign:Card materialDesign:ShadowAssist.ShadowDepth="Depth1" VerticalAlignment="Stretch" Margin="0,0,5,0">
<StackPanel Margin="15"> <StackPanel Margin="15">
<ListBox ItemsSource="{Binding NormalModules}" <Border BorderThickness="2" >
DisplayMemberPath="DisplayName" <Border.BorderBrush>
materialDesign:RippleAssist.IsDisabled="True" <VisualBrush>
dd:DragDrop.IsDragSource="True" <VisualBrush.Visual>
dd:DragDrop.IsDropTarget="True" <Rectangle StrokeDashArray="4 2" Stroke="{DynamicResource MaterialDesignDivider}" StrokeThickness="2"
dd:DragDrop.UseDefaultDragAdorner="True" Width="{Binding RelativeSource={RelativeSource AncestorType={x:Type Border}}, Path=ActualWidth}"
dd:DragDrop.DropHandler="{Binding ModulesDropHandler}" Height="{Binding RelativeSource={RelativeSource AncestorType={x:Type Border}}, Path=ActualHeight}"/>
MinHeight="30"/> </VisualBrush.Visual>
</VisualBrush>
</Border.BorderBrush>
<ListBox ItemsSource="{Binding NormalModules}"
materialDesign:RippleAssist.IsDisabled="True"
dd:DragDrop.IsDragSource="True"
dd:DragDrop.IsDropTarget="True"
dd:DragDrop.UseDefaultDragAdorner="True"
dd:DragDrop.DropHandler="{Binding}"
MinHeight="40">
<ListBox.ItemTemplate>
<DataTemplate>
<ContentControl s:View.Model="{Binding}" VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch" IsTabStop="False"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Border>
</StackPanel> </StackPanel>
</materialDesign:Card> </materialDesign:Card>
</StackPanel> </StackPanel>

View File

@ -1,54 +1,84 @@
using System.Linq; using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Artemis.Core.Plugins.Modules; using Artemis.Core.Plugins.Modules;
using Artemis.Core.Services.Interfaces; using Artemis.Core.Services.Interfaces;
using GongSolutions.Wpf.DragDrop;
using Stylet; using Stylet;
namespace Artemis.UI.Screens.Settings.Tabs.Modules namespace Artemis.UI.Screens.Settings.Tabs.Modules
{ {
public class ModuleOrderTabViewModel : Screen public class ModuleOrderTabViewModel : Screen, IDropTarget
{ {
private readonly IPluginService _pluginService; private readonly IPluginService _pluginService;
private readonly IModuleService _moduleService;
private List<ModuleOrderModuleViewModel> _modules;
private DefaultDropHandler _defaultDropHandler;
public ModuleOrderTabViewModel(IPluginService pluginService, IModuleService moduleService) public ModuleOrderTabViewModel(IPluginService pluginService, IModuleService moduleService)
{ {
DisplayName = "MODULE PRIORITY"; DisplayName = "MODULE PRIORITY";
_pluginService = pluginService; _pluginService = pluginService;
NormalModules = new BindableCollection<Core.Plugins.Modules.Module>(); _moduleService = moduleService;
ApplicationModules = new BindableCollection<Core.Plugins.Modules.Module>(); _modules = new List<ModuleOrderModuleViewModel>(pluginService.GetPluginsOfType<Module>().Select(m => new ModuleOrderModuleViewModel(m)));
OverlayModules = new BindableCollection<Core.Plugins.Modules.Module>(); _defaultDropHandler = new DefaultDropHandler();
ModulesDropHandler = new ModulesDropHandler(moduleService, NormalModules, ApplicationModules, OverlayModules); NormalModules = new BindableCollection<ModuleOrderModuleViewModel>();
ApplicationModules = new BindableCollection<ModuleOrderModuleViewModel>();
OverlayModules = new BindableCollection<ModuleOrderModuleViewModel>();
Update();
} }
public BindableCollection<Core.Plugins.Modules.Module> NormalModules { get; set; } public BindableCollection<ModuleOrderModuleViewModel> NormalModules { get; set; }
public BindableCollection<Core.Plugins.Modules.Module> ApplicationModules { get; set; } public BindableCollection<ModuleOrderModuleViewModel> ApplicationModules { get; set; }
public BindableCollection<Core.Plugins.Modules.Module> OverlayModules { get; set; } public BindableCollection<ModuleOrderModuleViewModel> OverlayModules { get; set; }
public ModulesDropHandler ModulesDropHandler { get; } public void DragOver(IDropInfo dropInfo)
protected override void OnActivate()
{ {
// Take it off the UI thread to avoid freezing on tab change _defaultDropHandler.DragOver(dropInfo);
Task.Run(() => }
{
NormalModules.Clear();
ApplicationModules.Clear();
OverlayModules.Clear();
var instances = _pluginService.GetPluginsOfType<Core.Plugins.Modules.Module>().ToList(); public void Drop(IDropInfo dropInfo)
foreach (var module in instances) {
{ if (dropInfo.TargetItem == dropInfo.Data)
if (module.PriorityCategory == ModulePriorityCategory.Normal) return;
NormalModules.Add(module);
else if (module.PriorityCategory == ModulePriorityCategory.Application) var viewModel = (ModuleOrderModuleViewModel) dropInfo.Data;
ApplicationModules.Add(module); var targetCollection = (BindableCollection<ModuleOrderModuleViewModel>) dropInfo.TargetCollection;
else if (module.PriorityCategory == ModulePriorityCategory.Overlay) var insertIndex = dropInfo.InsertIndex;
OverlayModules.Add(module);
} 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();
} }
} }
} }

View File

@ -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<Core.Plugins.Modules.Module> _normalModules;
private readonly BindableCollection<Core.Plugins.Modules.Module> _applicationModules;
private readonly BindableCollection<Core.Plugins.Modules.Module> _overlayModules;
private DefaultDropHandler _defaultDropHandler;
public ModulesDropHandler(IModuleService moduleService,
BindableCollection<Core.Plugins.Modules.Module> normalModules,
BindableCollection<Core.Plugins.Modules.Module> applicationModules,
BindableCollection<Core.Plugins.Modules.Module> 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<Core.Plugins.Modules.Module>) 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);
}
}
}
}