mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-13 05:48:35 +00:00
Modules - Added activation requirements tab
Profile editor - Only override active profile with profile editor tab open
This commit is contained in:
parent
90383f2e41
commit
8d756128e4
@ -15,5 +15,10 @@
|
||||
{
|
||||
return ActivationMet;
|
||||
}
|
||||
|
||||
public string GetUserFriendlyDescription()
|
||||
{
|
||||
return "No description available";
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -10,5 +10,11 @@
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
bool Evaluate();
|
||||
|
||||
/// <summary>
|
||||
/// Returns a user-friendly description of the activation requirement, should include parameters if applicable
|
||||
/// </summary>
|
||||
/// <returns>A user-friendly description of the activation requirement</returns>
|
||||
string GetUserFriendlyDescription();
|
||||
}
|
||||
}
|
||||
@ -43,5 +43,14 @@ namespace Artemis.Core.Plugins.Modules.ActivationRequirements
|
||||
? processes.Any(p => string.Equals(Path.GetDirectoryName(p.GetProcessFilename()), Location, StringComparison.CurrentCultureIgnoreCase))
|
||||
: processes.Any();
|
||||
}
|
||||
|
||||
public string GetUserFriendlyDescription()
|
||||
{
|
||||
var description = $"Requirement met when \"{ProcessName}.exe\" is running";
|
||||
if (Location != null)
|
||||
description += $" from \"{Location}\"";
|
||||
|
||||
return description;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -5,7 +5,9 @@ using Artemis.Core.Models.Profile.LayerProperties.Attributes;
|
||||
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.ProfileEditor;
|
||||
using Artemis.UI.Screens.ProfileEditor.DisplayConditions;
|
||||
using Artemis.UI.Screens.ProfileEditor.DisplayConditions.Abstract;
|
||||
@ -30,7 +32,10 @@ namespace Artemis.UI.Ninject.Factories
|
||||
|
||||
public interface IModuleVmFactory : IVmFactory
|
||||
{
|
||||
ModuleRootViewModel Create(Module module);
|
||||
ModuleRootViewModel CreateModuleRootViewModel(Module module);
|
||||
ProfileEditorViewModel CreateProfileEditorViewModel(ProfileModule module);
|
||||
ActivationRequirementsViewModel CreateActivationRequirementsViewModel(Module module);
|
||||
ActivationRequirementViewModel CreateActivationRequirementViewModel(IModuleActivationRequirement activationRequirement);
|
||||
}
|
||||
|
||||
public interface ISettingsVmFactory : IVmFactory
|
||||
@ -44,11 +49,6 @@ namespace Artemis.UI.Ninject.Factories
|
||||
DeviceDebugViewModel Create(ArtemisDevice device);
|
||||
}
|
||||
|
||||
public interface IProfileEditorVmFactory : IVmFactory
|
||||
{
|
||||
ProfileEditorViewModel Create(ProfileModule module);
|
||||
}
|
||||
|
||||
public interface IFolderVmFactory : IVmFactory
|
||||
{
|
||||
FolderViewModel Create(ProfileElement folder);
|
||||
|
||||
@ -1,9 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Artemis.Core.Plugins.Modules;
|
||||
using Artemis.Core.Services;
|
||||
using Artemis.Core.Services.Interfaces;
|
||||
using Artemis.UI.Ninject.Factories;
|
||||
using Ninject;
|
||||
using Ninject.Parameters;
|
||||
@ -13,17 +10,15 @@ namespace Artemis.UI.Screens.Module
|
||||
{
|
||||
public class ModuleRootViewModel : Conductor<Screen>.Collection.OneActive
|
||||
{
|
||||
private readonly IModuleService _moduleService;
|
||||
private readonly IProfileEditorVmFactory _profileEditorVmFactory;
|
||||
private readonly IKernel _kernel;
|
||||
private readonly IModuleVmFactory _moduleVmFactory;
|
||||
|
||||
public ModuleRootViewModel(Core.Plugins.Modules.Module module, IModuleService moduleService, IProfileEditorVmFactory profileEditorVmFactory, IKernel kernel)
|
||||
public ModuleRootViewModel(Core.Plugins.Modules.Module module, IModuleVmFactory moduleVmFactory, IKernel kernel)
|
||||
{
|
||||
DisplayName = module?.DisplayName;
|
||||
Module = module;
|
||||
|
||||
_moduleService = moduleService;
|
||||
_profileEditorVmFactory = profileEditorVmFactory;
|
||||
_moduleVmFactory = moduleVmFactory;
|
||||
_kernel = kernel;
|
||||
}
|
||||
|
||||
@ -31,31 +26,18 @@ namespace Artemis.UI.Screens.Module
|
||||
|
||||
protected override void OnActivate()
|
||||
{
|
||||
Task.Run(async () =>
|
||||
{
|
||||
await _moduleService.SetActiveModuleOverride(Module);
|
||||
await AddTabsAsync();
|
||||
});
|
||||
AddTabs();
|
||||
base.OnActivate();
|
||||
}
|
||||
|
||||
protected override void OnDeactivate()
|
||||
{
|
||||
Task.Run(async () =>
|
||||
{
|
||||
await _moduleService.SetActiveModuleOverride(null);
|
||||
});
|
||||
base.OnDeactivate();
|
||||
}
|
||||
|
||||
private async Task AddTabsAsync()
|
||||
private void AddTabs()
|
||||
{
|
||||
// Create the profile editor and module VMs
|
||||
if (Module is ProfileModule profileModule)
|
||||
{
|
||||
var profileEditor = _profileEditorVmFactory.Create(profileModule);
|
||||
Items.Add(profileEditor);
|
||||
}
|
||||
Items.Add(_moduleVmFactory.CreateProfileEditorViewModel(profileModule));
|
||||
|
||||
if (Module.ActivationRequirements.Any())
|
||||
Items.Add(_moduleVmFactory.CreateActivationRequirementsViewModel(Module));
|
||||
|
||||
if (Module.ModuleTabs != null)
|
||||
{
|
||||
|
||||
@ -0,0 +1,44 @@
|
||||
<UserControl x:Class="Artemis.UI.Screens.Module.Tabs.ActivationRequirementView"
|
||||
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.Module.Tabs"
|
||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800"
|
||||
d:DataContext="{d:DesignInstance local:ActivationRequirementViewModel}">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition />
|
||||
<RowDefinition />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<StackPanel Grid.Column="0">
|
||||
<TextBlock Style="{StaticResource MaterialDesignTextBlock}"
|
||||
Text="{Binding RequirementName}" />
|
||||
<TextBlock Style="{StaticResource MaterialDesignTextBlock}"
|
||||
Foreground="{DynamicResource MaterialDesignNavigationItemSubheader}"
|
||||
TextWrapping="Wrap"
|
||||
Text="{Binding RequirementDescription}" />
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Row="0" Grid.Column="1" VerticalAlignment="Center">
|
||||
<ToggleButton Style="{StaticResource MaterialDesignActionToggleButton}"
|
||||
Focusable="False"
|
||||
IsHitTestVisible="False"
|
||||
IsChecked="{Binding RequirementMet}">
|
||||
<ToggleButton.Content>
|
||||
<Border Background="#E74C4C" Width="32" Height="32">
|
||||
<materialDesign:PackIcon Kind="Close" VerticalAlignment="Center" HorizontalAlignment="Center" />
|
||||
</Border>
|
||||
</ToggleButton.Content>
|
||||
<materialDesign:ToggleButtonAssist.OnContent>
|
||||
<materialDesign:PackIcon Kind="Check" />
|
||||
</materialDesign:ToggleButtonAssist.OnContent>
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@ -0,0 +1,64 @@
|
||||
using System.Timers;
|
||||
using Artemis.Core.Plugins.Modules.ActivationRequirements;
|
||||
using Humanizer;
|
||||
using Stylet;
|
||||
|
||||
namespace Artemis.UI.Screens.Module.Tabs
|
||||
{
|
||||
public class ActivationRequirementViewModel : Screen
|
||||
{
|
||||
private readonly IModuleActivationRequirement _activationRequirement;
|
||||
private readonly Timer _updateTimer;
|
||||
private string _requirementDescription;
|
||||
private bool _requirementMet;
|
||||
|
||||
public ActivationRequirementViewModel(IModuleActivationRequirement activationRequirement)
|
||||
{
|
||||
_activationRequirement = activationRequirement;
|
||||
_updateTimer = new Timer(500);
|
||||
|
||||
RequirementName = activationRequirement.GetType().Name.Humanize();
|
||||
RequirementDescription = activationRequirement.GetUserFriendlyDescription();
|
||||
|
||||
_updateTimer.Elapsed += UpdateTimerOnElapsed;
|
||||
}
|
||||
|
||||
public string RequirementName { get; }
|
||||
|
||||
public string RequirementDescription
|
||||
{
|
||||
get => _requirementDescription;
|
||||
set => SetAndNotify(ref _requirementDescription, value);
|
||||
}
|
||||
|
||||
public bool RequirementMet
|
||||
{
|
||||
get => _requirementMet;
|
||||
set => SetAndNotify(ref _requirementMet, value);
|
||||
}
|
||||
|
||||
protected override void OnActivate()
|
||||
{
|
||||
Update();
|
||||
_updateTimer.Start();
|
||||
base.OnActivate();
|
||||
}
|
||||
|
||||
protected override void OnDeactivate()
|
||||
{
|
||||
_updateTimer.Stop();
|
||||
base.OnDeactivate();
|
||||
}
|
||||
|
||||
private void UpdateTimerOnElapsed(object sender, ElapsedEventArgs e)
|
||||
{
|
||||
Update();
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
RequirementDescription = _activationRequirement.GetUserFriendlyDescription();
|
||||
RequirementMet = _activationRequirement.Evaluate();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,53 @@
|
||||
<UserControl x:Class="Artemis.UI.Screens.Module.Tabs.ActivationRequirementsView"
|
||||
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.Module.Tabs"
|
||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||
xmlns:s="https://github.com/canton7/Stylet"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800"
|
||||
d:DataContext="{d:DesignInstance local:ActivationRequirementsViewModel}">
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled">
|
||||
<StackPanel Margin="15" MaxWidth="800">
|
||||
<!-- General settings -->
|
||||
<TextBlock Style="{StaticResource MaterialDesignHeadline5TextBlock}" Margin="0 15">Activation requirements</TextBlock>
|
||||
<TextBlock Margin="0 0 0 15" TextWrapping="Wrap" Style="{StaticResource MaterialDesignTextBlock}">
|
||||
This module has built-in activation requirements and won't activate until <Run Text="{Binding ActivationType}" FontWeight="Medium" Foreground="{StaticResource SecondaryAccentBrush}" />. <LineBreak />
|
||||
These requirements allow the module creator to decide when the module is activated and you cannot override them.
|
||||
</TextBlock>
|
||||
|
||||
<TextBlock Style="{StaticResource MaterialDesignTextBlock}"
|
||||
Foreground="{DynamicResource MaterialDesignNavigationItemSubheader}"
|
||||
TextWrapping="Wrap">
|
||||
Note: While you have the profile editor open the module is always activated and any other modules are deactivated.
|
||||
</TextBlock>
|
||||
|
||||
<materialDesign:Card materialDesign:ShadowAssist.ShadowDepth="Depth1" VerticalAlignment="Stretch" Margin="0,0,5,0">
|
||||
|
||||
<ItemsControl ItemsSource="{Binding Items}">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel>
|
||||
<Separator Margin="0 -10">
|
||||
<Separator.Style>
|
||||
<Style TargetType="Separator" BasedOn="{StaticResource MaterialDesignSeparator}">
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding RelativeSource={RelativeSource PreviousData}}" Value="{x:Null}">
|
||||
<Setter Property="Visibility" Value="Collapsed" />
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Separator.Style>
|
||||
</Separator>
|
||||
<ContentControl s:View.Model="{Binding}" VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch" IsTabStop="False" Margin="20" />
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
|
||||
</materialDesign:Card>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</UserControl>
|
||||
@ -0,0 +1,36 @@
|
||||
using System.Linq;
|
||||
using Artemis.Core.Plugins.Modules;
|
||||
using Artemis.UI.Ninject.Factories;
|
||||
using Stylet;
|
||||
|
||||
namespace Artemis.UI.Screens.Module.Tabs
|
||||
{
|
||||
public class ActivationRequirementsViewModel : Conductor<ActivationRequirementViewModel>.Collection.AllActive
|
||||
{
|
||||
private readonly IModuleVmFactory _moduleVmFactory;
|
||||
|
||||
public ActivationRequirementsViewModel(Core.Plugins.Modules.Module module, IModuleVmFactory moduleVmFactory)
|
||||
{
|
||||
_moduleVmFactory = moduleVmFactory;
|
||||
|
||||
DisplayName = "Activation requirements";
|
||||
Module = module;
|
||||
|
||||
ActivationType = Module.ActivationRequirementMode == ActivationRequirementType.All
|
||||
? "all requirements are met"
|
||||
: "any requirement is met";
|
||||
}
|
||||
|
||||
public Core.Plugins.Modules.Module Module { get; }
|
||||
|
||||
public string ActivationType { get; set; }
|
||||
|
||||
protected override void OnActivate()
|
||||
{
|
||||
if (!Items.Any())
|
||||
Items.AddRange(Module.ActivationRequirements.Select(_moduleVmFactory.CreateActivationRequirementViewModel));
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -7,6 +7,7 @@ using Artemis.Core.Models.Profile;
|
||||
using Artemis.Core.Plugins.Modules;
|
||||
using Artemis.Core.Plugins.Settings;
|
||||
using Artemis.Core.Services;
|
||||
using Artemis.Core.Services.Interfaces;
|
||||
using Artemis.Core.Services.Storage.Interfaces;
|
||||
using Artemis.UI.Screens.ProfileEditor.Dialogs;
|
||||
using Artemis.UI.Screens.ProfileEditor.DisplayConditions;
|
||||
@ -24,6 +25,7 @@ namespace Artemis.UI.Screens.ProfileEditor
|
||||
private readonly IProfileEditorService _profileEditorService;
|
||||
private readonly IProfileService _profileService;
|
||||
private readonly ISettingsService _settingsService;
|
||||
private readonly IModuleService _moduleService;
|
||||
private readonly ISnackbarMessageQueue _snackbarMessageQueue;
|
||||
private BindableCollection<ProfileDescriptor> _profiles;
|
||||
private PluginSetting<GridLength> _sidePanelsWidth;
|
||||
@ -42,11 +44,13 @@ namespace Artemis.UI.Screens.ProfileEditor
|
||||
IProfileService profileService,
|
||||
IDialogService dialogService,
|
||||
ISettingsService settingsService,
|
||||
IModuleService moduleService,
|
||||
ISnackbarMessageQueue snackbarMessageQueue)
|
||||
{
|
||||
_profileEditorService = profileEditorService;
|
||||
_profileService = profileService;
|
||||
_settingsService = settingsService;
|
||||
_moduleService = moduleService;
|
||||
_snackbarMessageQueue = snackbarMessageQueue;
|
||||
|
||||
DisplayName = "Profile editor";
|
||||
@ -233,19 +237,21 @@ namespace Artemis.UI.Screens.ProfileEditor
|
||||
LoadWorkspaceSettings();
|
||||
Module.IsProfileUpdatingDisabled = true;
|
||||
Module.ActiveProfileChanged += ModuleOnActiveProfileChanged;
|
||||
LoadProfiles();
|
||||
|
||||
Execute.PostToUIThread(LoadProfiles);
|
||||
Task.Run(async () => { await _moduleService.SetActiveModuleOverride(Module); });
|
||||
base.OnActivate();
|
||||
}
|
||||
|
||||
protected override void OnClose()
|
||||
protected override void OnDeactivate()
|
||||
{
|
||||
SaveWorkspaceSettings();
|
||||
Module.IsProfileUpdatingDisabled = false;
|
||||
Module.ActiveProfileChanged -= ModuleOnActiveProfileChanged;
|
||||
|
||||
_profileEditorService.ChangeSelectedProfile(null);
|
||||
base.OnClose();
|
||||
Task.Run(async () => { await _moduleService.SetActiveModuleOverride(null); });
|
||||
base.OnDeactivate();
|
||||
}
|
||||
|
||||
private void RemoveProfile(ProfileDescriptor profileDescriptor)
|
||||
@ -309,19 +315,6 @@ namespace Artemis.UI.Screens.ProfileEditor
|
||||
// Get all profiles from the database
|
||||
Profiles.Clear();
|
||||
Profiles.AddRange(_profileService.GetProfileDescriptors(Module).OrderBy(d => d.Name));
|
||||
|
||||
// Populate the selected profile
|
||||
var lastActiveProfile = Profiles.FirstOrDefault(p => p.IsLastActiveProfile) ?? Profiles.FirstOrDefault();
|
||||
if (lastActiveProfile != null)
|
||||
{
|
||||
SelectedProfile = lastActiveProfile;
|
||||
return;
|
||||
}
|
||||
|
||||
// Create a default profile if there is none
|
||||
var defaultProfile = _profileService.CreateProfileDescriptor(Module, "Default");
|
||||
Profiles.Add(defaultProfile);
|
||||
SelectedProfile = defaultProfile;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -211,7 +211,7 @@ namespace Artemis.UI.Screens.Sidebar
|
||||
|
||||
private void ActivateModule(INavigationItem sidebarItem)
|
||||
{
|
||||
SelectedItem = SidebarModules.ContainsKey(sidebarItem) ? _moduleVmFactory.Create(SidebarModules[sidebarItem]) : null;
|
||||
SelectedItem = SidebarModules.ContainsKey(sidebarItem) ? _moduleVmFactory.CreateModuleRootViewModel(SidebarModules[sidebarItem]) : null;
|
||||
}
|
||||
|
||||
#region Event handlers
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
using Artemis.Core.Plugins.Modules;
|
||||
using System;
|
||||
using System.IO;
|
||||
using Artemis.Core.Plugins.Modules;
|
||||
using Artemis.Core.Plugins.Modules.ActivationRequirements;
|
||||
|
||||
namespace Artemis.Plugins.Modules.Overlay
|
||||
@ -14,6 +16,11 @@ namespace Artemis.Plugins.Modules.Overlay
|
||||
DefaultPriorityCategory = ModulePriorityCategory.Overlay;
|
||||
|
||||
ActivationRequirements.Add(new ProcessActivationRequirement("taskmgr"));
|
||||
ActivationRequirements.Add(new ProcessActivationRequirement("calc"));
|
||||
ActivationRequirements.Add(new ProcessActivationRequirement("mspaint")
|
||||
{
|
||||
Location = Path.Combine(Directory.GetParent(Environment.GetFolderPath(Environment.SpecialFolder.System)).FullName, "System32")
|
||||
});
|
||||
}
|
||||
|
||||
// This is the end of your plugin life cycle.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user