mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-13 05:48:35 +00:00
Plugins - Implemented enabling/disabling (doesnt work for devices)
Plugins - Disable plugins that caused a crash Tray icon - Added menu items for quick access
This commit is contained in:
parent
16b221d2f8
commit
57d82fafa8
@ -9,11 +9,11 @@ namespace Artemis.Core.Ninject
|
|||||||
{
|
{
|
||||||
internal class PluginSettingsProvider : Provider<PluginSettings>
|
internal class PluginSettingsProvider : Provider<PluginSettings>
|
||||||
{
|
{
|
||||||
private readonly IPluginSettingRepository _pluginSettingRepository;
|
private readonly IPluginRepository _pluginRepository;
|
||||||
|
|
||||||
internal PluginSettingsProvider(IPluginSettingRepository pluginSettingRepository)
|
internal PluginSettingsProvider(IPluginRepository pluginRepository)
|
||||||
{
|
{
|
||||||
_pluginSettingRepository = pluginSettingRepository;
|
_pluginRepository = pluginRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override PluginSettings CreateInstance(IContext context)
|
protected override PluginSettings CreateInstance(IContext context)
|
||||||
@ -25,7 +25,7 @@ namespace Artemis.Core.Ninject
|
|||||||
if (pluginInfo == null)
|
if (pluginInfo == null)
|
||||||
throw new ArtemisCoreException("A plugin needs to be initialized with PluginInfo as a parameter");
|
throw new ArtemisCoreException("A plugin needs to be initialized with PluginInfo as a parameter");
|
||||||
|
|
||||||
return new PluginSettings(pluginInfo, _pluginSettingRepository);
|
return new PluginSettings(pluginInfo, _pluginRepository);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2,6 +2,7 @@
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using Artemis.Core.Plugins.Abstract;
|
using Artemis.Core.Plugins.Abstract;
|
||||||
|
using Artemis.Storage.Entities.Plugins;
|
||||||
using McMaster.NETCore.Plugins;
|
using McMaster.NETCore.Plugins;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
@ -72,6 +73,12 @@ namespace Artemis.Core.Plugins.Models
|
|||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
internal Assembly Assembly { get; set; }
|
internal Assembly Assembly { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The entity representing the plugin
|
||||||
|
/// </summary>
|
||||||
|
[JsonIgnore]
|
||||||
|
internal PluginEntity PluginEntity { get; set; }
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return $"{nameof(Guid)}: {Guid}, {nameof(Name)}: {Name}, {nameof(Version)}: {Version}";
|
return $"{nameof(Guid)}: {Guid}, {nameof(Name)}: {Name}, {nameof(Version)}: {Version}";
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using Artemis.Storage.Entities;
|
using Artemis.Storage.Entities;
|
||||||
|
using Artemis.Storage.Entities.Plugins;
|
||||||
using Artemis.Storage.Repositories.Interfaces;
|
using Artemis.Storage.Repositories.Interfaces;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
@ -10,13 +11,13 @@ namespace Artemis.Core.Plugins.Models
|
|||||||
// ReSharper disable once NotAccessedField.Local
|
// ReSharper disable once NotAccessedField.Local
|
||||||
private readonly PluginInfo _pluginInfo;
|
private readonly PluginInfo _pluginInfo;
|
||||||
private readonly PluginSettingEntity _pluginSettingEntity;
|
private readonly PluginSettingEntity _pluginSettingEntity;
|
||||||
private readonly IPluginSettingRepository _pluginSettingRepository;
|
private readonly IPluginRepository _pluginRepository;
|
||||||
private T _value;
|
private T _value;
|
||||||
|
|
||||||
internal PluginSetting(PluginInfo pluginInfo, IPluginSettingRepository pluginSettingRepository, PluginSettingEntity pluginSettingEntity)
|
internal PluginSetting(PluginInfo pluginInfo, IPluginRepository pluginRepository, PluginSettingEntity pluginSettingEntity)
|
||||||
{
|
{
|
||||||
_pluginInfo = pluginInfo;
|
_pluginInfo = pluginInfo;
|
||||||
_pluginSettingRepository = pluginSettingRepository;
|
_pluginRepository = pluginRepository;
|
||||||
_pluginSettingEntity = pluginSettingEntity;
|
_pluginSettingEntity = pluginSettingEntity;
|
||||||
|
|
||||||
Name = pluginSettingEntity.Name;
|
Name = pluginSettingEntity.Name;
|
||||||
@ -73,7 +74,7 @@ namespace Artemis.Core.Plugins.Models
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
_pluginSettingEntity.Value = JsonConvert.SerializeObject(Value);
|
_pluginSettingEntity.Value = JsonConvert.SerializeObject(Value);
|
||||||
_pluginSettingRepository.Save(_pluginSettingEntity);
|
_pluginRepository.SaveSetting(_pluginSettingEntity);
|
||||||
}
|
}
|
||||||
|
|
||||||
public event EventHandler<EventArgs> SettingChanged;
|
public event EventHandler<EventArgs> SettingChanged;
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Artemis.Storage.Entities;
|
using Artemis.Storage.Entities;
|
||||||
|
using Artemis.Storage.Entities.Plugins;
|
||||||
using Artemis.Storage.Repositories.Interfaces;
|
using Artemis.Storage.Repositories.Interfaces;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
@ -12,13 +13,13 @@ namespace Artemis.Core.Plugins.Models
|
|||||||
public class PluginSettings
|
public class PluginSettings
|
||||||
{
|
{
|
||||||
private readonly PluginInfo _pluginInfo;
|
private readonly PluginInfo _pluginInfo;
|
||||||
private readonly IPluginSettingRepository _pluginSettingRepository;
|
private readonly IPluginRepository _pluginRepository;
|
||||||
private readonly Dictionary<string, object> _settingEntities;
|
private readonly Dictionary<string, object> _settingEntities;
|
||||||
|
|
||||||
internal PluginSettings(PluginInfo pluginInfo, IPluginSettingRepository pluginSettingRepository)
|
internal PluginSettings(PluginInfo pluginInfo, IPluginRepository pluginRepository)
|
||||||
{
|
{
|
||||||
_pluginInfo = pluginInfo;
|
_pluginInfo = pluginInfo;
|
||||||
_pluginSettingRepository = pluginSettingRepository;
|
_pluginRepository = pluginRepository;
|
||||||
_settingEntities = new Dictionary<string, object>();
|
_settingEntities = new Dictionary<string, object>();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -37,15 +38,15 @@ namespace Artemis.Core.Plugins.Models
|
|||||||
if (_settingEntities.ContainsKey(name))
|
if (_settingEntities.ContainsKey(name))
|
||||||
return (PluginSetting<T>) _settingEntities[name];
|
return (PluginSetting<T>) _settingEntities[name];
|
||||||
// Try to find in database
|
// Try to find in database
|
||||||
var settingEntity = _pluginSettingRepository.GetByNameAndPluginGuid(name, _pluginInfo.Guid);
|
var settingEntity = _pluginRepository.GetSettingByNameAndGuid(name, _pluginInfo.Guid);
|
||||||
// If not found, create a new one
|
// If not found, create a new one
|
||||||
if (settingEntity == null)
|
if (settingEntity == null)
|
||||||
{
|
{
|
||||||
settingEntity = new PluginSettingEntity {Name = name, PluginGuid = _pluginInfo.Guid, Value = JsonConvert.SerializeObject(defaultValue)};
|
settingEntity = new PluginSettingEntity {Name = name, PluginGuid = _pluginInfo.Guid, Value = JsonConvert.SerializeObject(defaultValue)};
|
||||||
_pluginSettingRepository.Add(settingEntity);
|
_pluginRepository.AddSetting(settingEntity);
|
||||||
}
|
}
|
||||||
|
|
||||||
var pluginSetting = new PluginSetting<T>(_pluginInfo, _pluginSettingRepository, settingEntity);
|
var pluginSetting = new PluginSetting<T>(_pluginInfo, _pluginRepository, settingEntity);
|
||||||
_settingEntities.Add(name, pluginSetting);
|
_settingEntities.Add(name, pluginSetting);
|
||||||
return pluginSetting;
|
return pluginSetting;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -42,6 +42,18 @@ namespace Artemis.Core.Services.Interfaces
|
|||||||
/// <param name="pluginInfo">The plugin info defining the plugin to unload</param>
|
/// <param name="pluginInfo">The plugin info defining the plugin to unload</param>
|
||||||
void UnloadPlugin(PluginInfo pluginInfo);
|
void UnloadPlugin(PluginInfo pluginInfo);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Enables the provided plugin
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="plugin"></param>
|
||||||
|
void EnablePlugin(Plugin plugin);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Disables the provided plugin
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="plugin"></param>
|
||||||
|
void DisablePlugin(Plugin plugin);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Finds the plugin info related to the plugin
|
/// Finds the plugin info related to the plugin
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@ -10,6 +10,8 @@ using Artemis.Core.Plugins.Abstract;
|
|||||||
using Artemis.Core.Plugins.Exceptions;
|
using Artemis.Core.Plugins.Exceptions;
|
||||||
using Artemis.Core.Plugins.Models;
|
using Artemis.Core.Plugins.Models;
|
||||||
using Artemis.Core.Services.Interfaces;
|
using Artemis.Core.Services.Interfaces;
|
||||||
|
using Artemis.Storage.Entities.Plugins;
|
||||||
|
using Artemis.Storage.Repositories.Interfaces;
|
||||||
using McMaster.NETCore.Plugins;
|
using McMaster.NETCore.Plugins;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Ninject;
|
using Ninject;
|
||||||
@ -27,13 +29,15 @@ namespace Artemis.Core.Services
|
|||||||
{
|
{
|
||||||
private readonly IKernel _kernel;
|
private readonly IKernel _kernel;
|
||||||
private readonly ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
|
private readonly IPluginRepository _pluginRepository;
|
||||||
private readonly List<PluginInfo> _plugins;
|
private readonly List<PluginInfo> _plugins;
|
||||||
private IKernel _childKernel;
|
private IKernel _childKernel;
|
||||||
|
|
||||||
internal PluginService(IKernel kernel, ILogger logger)
|
internal PluginService(IKernel kernel, ILogger logger, IPluginRepository pluginRepository)
|
||||||
{
|
{
|
||||||
_kernel = kernel;
|
_kernel = kernel;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
|
_pluginRepository = pluginRepository;
|
||||||
_plugins = new List<PluginInfo>();
|
_plugins = new List<PluginInfo>();
|
||||||
|
|
||||||
// Ensure the plugins directory exists
|
// Ensure the plugins directory exists
|
||||||
@ -146,6 +150,18 @@ namespace Artemis.Core.Services
|
|||||||
// Activate plugins after they are all loaded
|
// Activate plugins after they are all loaded
|
||||||
foreach (var pluginInfo in _plugins.Where(p => p.Enabled))
|
foreach (var pluginInfo in _plugins.Where(p => p.Enabled))
|
||||||
{
|
{
|
||||||
|
if (!pluginInfo.PluginEntity.LastEnableSuccessful)
|
||||||
|
{
|
||||||
|
pluginInfo.Enabled = false;
|
||||||
|
_logger.Warning("Plugin failed to load last time, disabling it now to avoid instability. Plugin info: {pluginInfo}", pluginInfo);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mark this as false until the plugin enabled successfully and save it in case the plugin drags us down into a crash
|
||||||
|
pluginInfo.PluginEntity.LastEnableSuccessful = false;
|
||||||
|
_pluginRepository.SavePlugin(pluginInfo.PluginEntity);
|
||||||
|
|
||||||
|
var threwException = false;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
pluginInfo.Instance.EnablePlugin();
|
pluginInfo.Instance.EnablePlugin();
|
||||||
@ -153,6 +169,15 @@ namespace Artemis.Core.Services
|
|||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
_logger.Warning(new ArtemisPluginException(pluginInfo, "Failed to load enable plugin", e), "Plugin exception");
|
_logger.Warning(new ArtemisPluginException(pluginInfo, "Failed to load enable plugin", e), "Plugin exception");
|
||||||
|
pluginInfo.Enabled = false;
|
||||||
|
threwException = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We got this far so the plugin enabled and we didn't crash horribly, yay
|
||||||
|
if (!threwException)
|
||||||
|
{
|
||||||
|
pluginInfo.PluginEntity.LastEnableSuccessful = true;
|
||||||
|
_pluginRepository.SavePlugin(pluginInfo.PluginEntity);
|
||||||
}
|
}
|
||||||
|
|
||||||
OnPluginEnabled(new PluginEventArgs(pluginInfo));
|
OnPluginEnabled(new PluginEventArgs(pluginInfo));
|
||||||
@ -191,8 +216,13 @@ namespace Artemis.Core.Services
|
|||||||
if (_plugins.Contains(pluginInfo))
|
if (_plugins.Contains(pluginInfo))
|
||||||
UnloadPlugin(pluginInfo);
|
UnloadPlugin(pluginInfo);
|
||||||
|
|
||||||
// TODO Just temporarily until settings are in place
|
var pluginEntity = _pluginRepository.GetPluginByGuid(pluginInfo.Guid);
|
||||||
pluginInfo.Enabled = true;
|
if (pluginEntity == null)
|
||||||
|
pluginEntity = new PluginEntity {PluginGuid = pluginInfo.Guid, IsEnabled = true, LastEnableSuccessful = true};
|
||||||
|
|
||||||
|
pluginInfo.PluginEntity = pluginEntity;
|
||||||
|
pluginInfo.Enabled = pluginEntity.IsEnabled;
|
||||||
|
|
||||||
var mainFile = Path.Combine(pluginInfo.Directory.FullName, pluginInfo.Main);
|
var mainFile = Path.Combine(pluginInfo.Directory.FullName, pluginInfo.Main);
|
||||||
if (!File.Exists(mainFile))
|
if (!File.Exists(mainFile))
|
||||||
throw new ArtemisPluginException(pluginInfo, "Couldn't find the plugins main entry at " + mainFile);
|
throw new ArtemisPluginException(pluginInfo, "Couldn't find the plugins main entry at " + mainFile);
|
||||||
@ -277,6 +307,49 @@ namespace Artemis.Core.Services
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void EnablePlugin(Plugin plugin)
|
||||||
|
{
|
||||||
|
plugin.PluginInfo.Enabled = true;
|
||||||
|
plugin.PluginInfo.PluginEntity.IsEnabled = true;
|
||||||
|
plugin.PluginInfo.PluginEntity.LastEnableSuccessful = false;
|
||||||
|
_pluginRepository.SavePlugin(plugin.PluginInfo.PluginEntity);
|
||||||
|
|
||||||
|
var threwException = false;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
plugin.EnablePlugin();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
_logger.Warning(new ArtemisPluginException(plugin.PluginInfo, "Failed to enable plugin", e), "Plugin exception");
|
||||||
|
plugin.PluginInfo.Enabled = false;
|
||||||
|
threwException = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We got this far so the plugin enabled and we didn't crash horribly, yay
|
||||||
|
if (!threwException)
|
||||||
|
{
|
||||||
|
plugin.PluginInfo.PluginEntity.LastEnableSuccessful = true;
|
||||||
|
_pluginRepository.SavePlugin(plugin.PluginInfo.PluginEntity);
|
||||||
|
}
|
||||||
|
|
||||||
|
OnPluginEnabled(new PluginEventArgs(plugin.PluginInfo));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DisablePlugin(Plugin plugin)
|
||||||
|
{
|
||||||
|
plugin.PluginInfo.Enabled = false;
|
||||||
|
plugin.PluginInfo.PluginEntity.IsEnabled = false;
|
||||||
|
_pluginRepository.SavePlugin(plugin.PluginInfo.PluginEntity);
|
||||||
|
|
||||||
|
plugin.DisablePlugin();
|
||||||
|
|
||||||
|
// We got this far so the plugin enabled and we didn't crash horribly, yay
|
||||||
|
_pluginRepository.SavePlugin(plugin.PluginInfo.PluginEntity);
|
||||||
|
|
||||||
|
OnPluginDisabled(new PluginEventArgs(plugin.PluginInfo));
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public PluginInfo GetPluginInfo(Plugin plugin)
|
public PluginInfo GetPluginInfo(Plugin plugin)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -61,6 +61,7 @@ namespace Artemis.Core.Services
|
|||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
_logger.Error(e, "Exception during device loading for device provider {deviceProvider}", deviceProvider.GetType().Name);
|
_logger.Error(e, "Exception during device loading for device provider {deviceProvider}", deviceProvider.GetType().Name);
|
||||||
|
throw e;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (deviceProvider.Devices == null)
|
if (deviceProvider.Devices == null)
|
||||||
|
|||||||
@ -9,9 +9,9 @@ namespace Artemis.Core.Services
|
|||||||
{
|
{
|
||||||
private readonly PluginSettings _pluginSettings;
|
private readonly PluginSettings _pluginSettings;
|
||||||
|
|
||||||
internal SettingsService(IPluginSettingRepository pluginSettingRepository)
|
internal SettingsService(IPluginRepository pluginRepository)
|
||||||
{
|
{
|
||||||
_pluginSettings = new PluginSettings(Constants.CorePluginInfo, pluginSettingRepository);
|
_pluginSettings = new PluginSettings(Constants.CorePluginInfo, pluginRepository);
|
||||||
}
|
}
|
||||||
|
|
||||||
public PluginSetting<T> GetSetting<T>(string name, T defaultValue = default)
|
public PluginSetting<T> GetSetting<T>(string name, T defaultValue = default)
|
||||||
|
|||||||
16
src/Artemis.Storage/Entities/Plugins/PluginEntity.cs
Normal file
16
src/Artemis.Storage/Entities/Plugins/PluginEntity.cs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Artemis.Storage.Entities.Plugins
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents the configuration of a plugin, each plugin has one configuration
|
||||||
|
/// </summary>
|
||||||
|
public class PluginEntity
|
||||||
|
{
|
||||||
|
public Guid Id { get; set; }
|
||||||
|
public Guid PluginGuid { get; set; }
|
||||||
|
|
||||||
|
public bool IsEnabled { get; set; }
|
||||||
|
public bool LastEnableSuccessful { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,7 +1,10 @@
|
|||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Artemis.Storage.Entities
|
namespace Artemis.Storage.Entities.Plugins
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents the setting of a plugin, a plugin can have multiple settings
|
||||||
|
/// </summary>
|
||||||
public class PluginSettingEntity
|
public class PluginSettingEntity
|
||||||
{
|
{
|
||||||
public Guid Id { get; set; }
|
public Guid Id { get; set; }
|
||||||
@ -0,0 +1,16 @@
|
|||||||
|
using System;
|
||||||
|
using Artemis.Storage.Entities.Plugins;
|
||||||
|
|
||||||
|
namespace Artemis.Storage.Repositories.Interfaces
|
||||||
|
{
|
||||||
|
public interface IPluginRepository : IRepository
|
||||||
|
{
|
||||||
|
void AddPlugin(PluginEntity pluginEntity);
|
||||||
|
PluginEntity GetPluginByGuid(Guid pluginGuid);
|
||||||
|
void SavePlugin(PluginEntity pluginEntity);
|
||||||
|
void AddSetting(PluginSettingEntity pluginSettingEntity);
|
||||||
|
PluginSettingEntity GetSettingByGuid(Guid pluginGuid);
|
||||||
|
PluginSettingEntity GetSettingByNameAndGuid(string name, Guid pluginGuid);
|
||||||
|
void SaveSetting(PluginSettingEntity pluginSettingEntity);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,14 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using Artemis.Storage.Entities;
|
|
||||||
|
|
||||||
namespace Artemis.Storage.Repositories.Interfaces
|
|
||||||
{
|
|
||||||
public interface IPluginSettingRepository : IRepository
|
|
||||||
{
|
|
||||||
void Add(PluginSettingEntity pluginSettingEntity);
|
|
||||||
List<PluginSettingEntity> GetByPluginGuid(Guid pluginGuid);
|
|
||||||
PluginSettingEntity GetByNameAndPluginGuid(string name, Guid pluginGuid);
|
|
||||||
void Save(PluginSettingEntity pluginSettingEntity);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
56
src/Artemis.Storage/Repositories/PluginRepository.cs
Normal file
56
src/Artemis.Storage/Repositories/PluginRepository.cs
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
using System;
|
||||||
|
using Artemis.Storage.Entities.Plugins;
|
||||||
|
using Artemis.Storage.Repositories.Interfaces;
|
||||||
|
using LiteDB;
|
||||||
|
|
||||||
|
namespace Artemis.Storage.Repositories
|
||||||
|
{
|
||||||
|
public class PluginRepository : IPluginRepository
|
||||||
|
{
|
||||||
|
private readonly LiteRepository _repository;
|
||||||
|
|
||||||
|
internal PluginRepository(LiteRepository repository)
|
||||||
|
{
|
||||||
|
_repository = repository;
|
||||||
|
|
||||||
|
_repository.Database.GetCollection<PluginEntity>().EnsureIndex(s => s.PluginGuid);
|
||||||
|
_repository.Database.GetCollection<PluginSettingEntity>().EnsureIndex(s => s.Name);
|
||||||
|
_repository.Database.GetCollection<PluginSettingEntity>().EnsureIndex(s => s.PluginGuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddPlugin(PluginEntity pluginEntity)
|
||||||
|
{
|
||||||
|
_repository.Insert(pluginEntity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PluginEntity GetPluginByGuid(Guid pluginGuid)
|
||||||
|
{
|
||||||
|
return _repository.FirstOrDefault<PluginEntity>(p => p.PluginGuid == pluginGuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SavePlugin(PluginEntity pluginEntity)
|
||||||
|
{
|
||||||
|
_repository.Upsert(pluginEntity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddSetting(PluginSettingEntity pluginSettingEntity)
|
||||||
|
{
|
||||||
|
_repository.Insert(pluginSettingEntity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PluginSettingEntity GetSettingByGuid(Guid pluginGuid)
|
||||||
|
{
|
||||||
|
return _repository.FirstOrDefault<PluginSettingEntity>(p => p.PluginGuid == pluginGuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PluginSettingEntity GetSettingByNameAndGuid(string name, Guid pluginGuid)
|
||||||
|
{
|
||||||
|
return _repository.FirstOrDefault<PluginSettingEntity>(p => p.Name == name && p.PluginGuid == pluginGuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SaveSetting(PluginSettingEntity pluginSettingEntity)
|
||||||
|
{
|
||||||
|
_repository.Upsert(pluginSettingEntity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,40 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using Artemis.Storage.Entities;
|
|
||||||
using Artemis.Storage.Repositories.Interfaces;
|
|
||||||
using LiteDB;
|
|
||||||
|
|
||||||
namespace Artemis.Storage.Repositories
|
|
||||||
{
|
|
||||||
public class PluginSettingRepository : IPluginSettingRepository
|
|
||||||
{
|
|
||||||
private readonly LiteRepository _repository;
|
|
||||||
|
|
||||||
internal PluginSettingRepository(LiteRepository repository)
|
|
||||||
{
|
|
||||||
_repository = repository;
|
|
||||||
_repository.Database.GetCollection<PluginSettingEntity>().EnsureIndex(s => s.Name);
|
|
||||||
_repository.Database.GetCollection<PluginSettingEntity>().EnsureIndex(s => s.PluginGuid);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Add(PluginSettingEntity pluginSettingEntity)
|
|
||||||
{
|
|
||||||
_repository.Insert(pluginSettingEntity);
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<PluginSettingEntity> GetByPluginGuid(Guid pluginGuid)
|
|
||||||
{
|
|
||||||
return _repository.Query<PluginSettingEntity>().Where(p => p.PluginGuid == pluginGuid).ToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
public PluginSettingEntity GetByNameAndPluginGuid(string name, Guid pluginGuid)
|
|
||||||
{
|
|
||||||
return _repository.FirstOrDefault<PluginSettingEntity>(p => p.Name == name && p.PluginGuid == pluginGuid);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Save(PluginSettingEntity pluginSettingEntity)
|
|
||||||
{
|
|
||||||
_repository.Upsert(pluginSettingEntity);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -49,11 +49,6 @@
|
|||||||
<Private>false</Private>
|
<Private>false</Private>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
|
||||||
<Reference Include="MaterialDesignExtensions">
|
|
||||||
<HintPath>..\..\..\..\.nuget\materialdesignextensions\3.0.0\lib\netcoreapp3.0\MaterialDesignExtensions.dll</HintPath>
|
|
||||||
</Reference>
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Resource Include="Resources\Fonts\RobotoMono-Regular.ttf" />
|
<Resource Include="Resources\Fonts\RobotoMono-Regular.ttf" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|||||||
@ -7,6 +7,7 @@
|
|||||||
xmlns:controls="clr-namespace:MaterialDesignExtensions.Controls;assembly=MaterialDesignExtensions"
|
xmlns:controls="clr-namespace:MaterialDesignExtensions.Controls;assembly=MaterialDesignExtensions"
|
||||||
xmlns:s="https://github.com/canton7/Stylet"
|
xmlns:s="https://github.com/canton7/Stylet"
|
||||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||||
|
xmlns:shared="clr-namespace:Artemis.UI.Shared"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
Title="Gradient Editor"
|
Title="Gradient Editor"
|
||||||
Background="{DynamicResource MaterialDesignPaper}"
|
Background="{DynamicResource MaterialDesignPaper}"
|
||||||
@ -18,7 +19,41 @@
|
|||||||
Icon="/Resources/Images/Logo/logo-512.png"
|
Icon="/Resources/Images/Logo/logo-512.png"
|
||||||
d:DesignHeight="450"
|
d:DesignHeight="450"
|
||||||
d:DesignWidth="800">
|
d:DesignWidth="800">
|
||||||
<Grid>
|
<StackPanel>
|
||||||
|
<materialDesign:Card >
|
||||||
|
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Top" Margin="16">
|
||||||
|
<materialDesign:PackIcon Kind="Crane" Width="80" Height="80" HorizontalAlignment="Center" />
|
||||||
|
<TextBlock Style="{StaticResource MaterialDesignBody1TextBlock}" TextWrapping="Wrap" HorizontalAlignment="Center" Margin="0 15">
|
||||||
|
Gradient saving not implemented yet
|
||||||
|
</TextBlock>
|
||||||
|
<TextBlock Style="{StaticResource MaterialDesignCaptionTextBlock}" TextWrapping="Wrap" HorizontalAlignment="Center">
|
||||||
|
Soon you'll be able to store different gradients for usage throughout your profiles and quickly select them
|
||||||
|
</TextBlock>
|
||||||
|
</StackPanel>
|
||||||
|
</materialDesign:Card>
|
||||||
|
|
||||||
</Grid>
|
<materialDesign:Card>
|
||||||
|
<Grid>
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition />
|
||||||
|
<RowDefinition />
|
||||||
|
<RowDefinition />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition />
|
||||||
|
<ColumnDefinition />
|
||||||
|
<ColumnDefinition />
|
||||||
|
<ColumnDefinition />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
|
<Separator Grid.Row="1" Grid.ColumnSpan="4" Style="{StaticResource MaterialDesignDarkSeparator}" Margin="8 0 8 0" />
|
||||||
|
|
||||||
|
<Label Grid.Row="0" Grid.Column="0">Color:</Label>
|
||||||
|
<shared:ColorPicker x:Name="CurrentColor" Grid.Row="0" Grid.Column="1" />
|
||||||
|
|
||||||
|
<Label Grid.Row="0" Grid.Column="2">Location:</Label>
|
||||||
|
<TextBox x:Name="CurrentLocation" Grid.Row="0" Grid.Column="3" />
|
||||||
|
</Grid>
|
||||||
|
</materialDesign:Card>
|
||||||
|
</StackPanel>
|
||||||
</controls:MaterialWindow>
|
</controls:MaterialWindow>
|
||||||
12
src/Artemis.UI/Events/RequestSelectSidebarItemEvent.cs
Normal file
12
src/Artemis.UI/Events/RequestSelectSidebarItemEvent.cs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
namespace Artemis.UI.Events
|
||||||
|
{
|
||||||
|
public class RequestSelectSidebarItemEvent
|
||||||
|
{
|
||||||
|
public string Label { get; }
|
||||||
|
|
||||||
|
public RequestSelectSidebarItemEvent(string label)
|
||||||
|
{
|
||||||
|
Label = label;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -23,6 +23,8 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties
|
|||||||
private readonly ICoreService _coreService;
|
private readonly ICoreService _coreService;
|
||||||
private readonly List<LayerPropertyViewModel> _layerPropertyViewModels;
|
private readonly List<LayerPropertyViewModel> _layerPropertyViewModels;
|
||||||
private readonly ILayerPropertyVmFactory _layerPropertyVmFactory;
|
private readonly ILayerPropertyVmFactory _layerPropertyVmFactory;
|
||||||
|
private readonly IPropertyTreeVmFactory _propertyTreeVmFactory;
|
||||||
|
private readonly IPropertyTimelineVmFactory _propertyTimelineVmFactory;
|
||||||
private readonly IProfileEditorService _profileEditorService;
|
private readonly IProfileEditorService _profileEditorService;
|
||||||
private readonly ISettingsService _settingsService;
|
private readonly ISettingsService _settingsService;
|
||||||
|
|
||||||
@ -37,14 +39,12 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties
|
|||||||
_coreService = coreService;
|
_coreService = coreService;
|
||||||
_settingsService = settingsService;
|
_settingsService = settingsService;
|
||||||
_layerPropertyVmFactory = layerPropertyVmFactory;
|
_layerPropertyVmFactory = layerPropertyVmFactory;
|
||||||
|
_propertyTreeVmFactory = propertyTreeVmFactory;
|
||||||
|
_propertyTimelineVmFactory = propertyTimelineVmFactory;
|
||||||
_layerPropertyViewModels = new List<LayerPropertyViewModel>();
|
_layerPropertyViewModels = new List<LayerPropertyViewModel>();
|
||||||
|
|
||||||
PixelsPerSecond = 31;
|
PixelsPerSecond = 31;
|
||||||
PropertyTree = propertyTreeVmFactory.Create(this);
|
}
|
||||||
PropertyTimeline = propertyTimelineVmFactory.Create(this);
|
|
||||||
|
|
||||||
PopulateProperties(_profileEditorService.SelectedProfileElement, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Playing { get; set; }
|
public bool Playing { get; set; }
|
||||||
public bool RepeatAfterLastKeyframe { get; set; }
|
public bool RepeatAfterLastKeyframe { get; set; }
|
||||||
@ -71,6 +71,11 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties
|
|||||||
|
|
||||||
protected override void OnInitialActivate()
|
protected override void OnInitialActivate()
|
||||||
{
|
{
|
||||||
|
PropertyTree = _propertyTreeVmFactory.Create(this);
|
||||||
|
PropertyTimeline = _propertyTimelineVmFactory.Create(this);
|
||||||
|
|
||||||
|
PopulateProperties(_profileEditorService.SelectedProfileElement, null);
|
||||||
|
|
||||||
_profileEditorService.ProfileElementSelected += ProfileEditorServiceOnProfileElementSelected;
|
_profileEditorService.ProfileElementSelected += ProfileEditorServiceOnProfileElementSelected;
|
||||||
_profileEditorService.CurrentTimeChanged += ProfileEditorServiceOnCurrentTimeChanged;
|
_profileEditorService.CurrentTimeChanged += ProfileEditorServiceOnCurrentTimeChanged;
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,6 @@
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
using Artemis.Core.Services;
|
|
||||||
using Artemis.UI.Events;
|
using Artemis.UI.Events;
|
||||||
using Artemis.UI.Screens.Sidebar;
|
using Artemis.UI.Screens.Sidebar;
|
||||||
using Artemis.UI.Utilities;
|
using Artemis.UI.Utilities;
|
||||||
|
|||||||
@ -186,10 +186,9 @@ namespace Artemis.UI.Screens.Settings
|
|||||||
foreach (var device in _surfaceService.ActiveSurface.Devices)
|
foreach (var device in _surfaceService.ActiveSurface.Devices)
|
||||||
DeviceSettingsViewModels.Add(_deviceSettingsVmFactory.Create(device));
|
DeviceSettingsViewModels.Add(_deviceSettingsVmFactory.Create(device));
|
||||||
|
|
||||||
// TODO: GetPluginsOfType isn't ideal here as it doesn't include disabled plugins
|
|
||||||
Plugins.Clear();
|
Plugins.Clear();
|
||||||
foreach (var plugin in _pluginService.GetPluginsOfType<Plugin>())
|
foreach (var pluginInfo in _pluginService.GetAllPluginInfo())
|
||||||
Plugins.Add(new PluginSettingsViewModel(plugin, _windowManager, _dialogService));
|
Plugins.Add(new PluginSettingsViewModel(pluginInfo.Instance, _windowManager, _dialogService, _pluginService));
|
||||||
|
|
||||||
base.OnInitialActivate();
|
base.OnInitialActivate();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Artemis.Core.Plugins.Abstract;
|
using Artemis.Core.Plugins.Abstract;
|
||||||
|
using Artemis.Core.Services.Interfaces;
|
||||||
using Artemis.UI.Shared.Services.Interfaces;
|
using Artemis.UI.Shared.Services.Interfaces;
|
||||||
using Stylet;
|
using Stylet;
|
||||||
|
|
||||||
@ -10,21 +11,27 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
|
|||||||
{
|
{
|
||||||
private readonly IDialogService _dialogService;
|
private readonly IDialogService _dialogService;
|
||||||
private readonly Plugin _plugin;
|
private readonly Plugin _plugin;
|
||||||
|
private readonly IPluginService _pluginService;
|
||||||
private readonly IWindowManager _windowManager;
|
private readonly IWindowManager _windowManager;
|
||||||
|
|
||||||
public PluginSettingsViewModel(Plugin plugin, IWindowManager windowManager, IDialogService dialogService)
|
public PluginSettingsViewModel(Plugin plugin, IWindowManager windowManager, IDialogService dialogService, IPluginService pluginService)
|
||||||
{
|
{
|
||||||
_plugin = plugin;
|
_plugin = plugin;
|
||||||
_windowManager = windowManager;
|
_windowManager = windowManager;
|
||||||
_dialogService = dialogService;
|
_dialogService = dialogService;
|
||||||
IsEnabled = true;
|
_pluginService = pluginService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Type => _plugin.GetType().BaseType?.Name ?? _plugin.GetType().Name;
|
public string Type => _plugin.GetType().BaseType?.Name ?? _plugin.GetType().Name;
|
||||||
public string Name => _plugin.PluginInfo.Name;
|
public string Name => _plugin.PluginInfo.Name;
|
||||||
public string Description => _plugin.PluginInfo.Description;
|
public string Description => _plugin.PluginInfo.Description;
|
||||||
public Version Version => _plugin.PluginInfo.Version;
|
public Version Version => _plugin.PluginInfo.Version;
|
||||||
public bool IsEnabled { get; set; }
|
|
||||||
|
public bool IsEnabled
|
||||||
|
{
|
||||||
|
get => _plugin.PluginInfo.Enabled;
|
||||||
|
set => Task.Run(() => UpdateEnabled(value));
|
||||||
|
}
|
||||||
|
|
||||||
public bool CanOpenSettings => IsEnabled && _plugin.HasConfigurationViewModel;
|
public bool CanOpenSettings => IsEnabled && _plugin.HasConfigurationViewModel;
|
||||||
|
|
||||||
@ -42,5 +49,16 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
|
|||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void UpdateEnabled(in bool enable)
|
||||||
|
{
|
||||||
|
if (_plugin.PluginInfo.Enabled == enable)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (enable)
|
||||||
|
_pluginService.EnablePlugin(_plugin);
|
||||||
|
else
|
||||||
|
_pluginService.DisablePlugin(_plugin);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -25,7 +25,7 @@
|
|||||||
</ComboBox>
|
</ComboBox>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
<controls:SideNavigation Items="{Binding SidebarItems}" WillSelectNavigationItemCommand="{s:Action SelectItem}" />
|
<controls:SideNavigation Items="{Binding SidebarItems}" SelectedItem="{Binding SelectedItem}" WillSelectNavigationItemCommand="{s:Action SelectItem}" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
</UserControl>
|
</UserControl>
|
||||||
@ -4,6 +4,7 @@ using System.Linq;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Artemis.Core.Events;
|
using Artemis.Core.Events;
|
||||||
using Artemis.Core.Services.Interfaces;
|
using Artemis.Core.Services.Interfaces;
|
||||||
|
using Artemis.UI.Events;
|
||||||
using Artemis.UI.Ninject.Factories;
|
using Artemis.UI.Ninject.Factories;
|
||||||
using Artemis.UI.Screens.Home;
|
using Artemis.UI.Screens.Home;
|
||||||
using Artemis.UI.Screens.News;
|
using Artemis.UI.Screens.News;
|
||||||
@ -18,13 +19,13 @@ using Stylet;
|
|||||||
|
|
||||||
namespace Artemis.UI.Screens.Sidebar
|
namespace Artemis.UI.Screens.Sidebar
|
||||||
{
|
{
|
||||||
public class SidebarViewModel : PropertyChangedBase
|
public class SidebarViewModel : PropertyChangedBase, IHandle<RequestSelectSidebarItemEvent>
|
||||||
{
|
{
|
||||||
private readonly IKernel _kernel;
|
private readonly IKernel _kernel;
|
||||||
private readonly IModuleVmFactory _moduleVmFactory;
|
private readonly IModuleVmFactory _moduleVmFactory;
|
||||||
private readonly IPluginService _pluginService;
|
private readonly IPluginService _pluginService;
|
||||||
|
|
||||||
public SidebarViewModel(IKernel kernel, IModuleVmFactory moduleVmFactory, IPluginService pluginService)
|
public SidebarViewModel(IKernel kernel, IEventAggregator eventAggregator, IModuleVmFactory moduleVmFactory, IPluginService pluginService)
|
||||||
{
|
{
|
||||||
_kernel = kernel;
|
_kernel = kernel;
|
||||||
_moduleVmFactory = moduleVmFactory;
|
_moduleVmFactory = moduleVmFactory;
|
||||||
@ -36,6 +37,8 @@ namespace Artemis.UI.Screens.Sidebar
|
|||||||
SetupSidebar();
|
SetupSidebar();
|
||||||
_pluginService.PluginEnabled += PluginServiceOnPluginEnabled;
|
_pluginService.PluginEnabled += PluginServiceOnPluginEnabled;
|
||||||
_pluginService.PluginDisabled += PluginServiceOnPluginDisabled;
|
_pluginService.PluginDisabled += PluginServiceOnPluginDisabled;
|
||||||
|
|
||||||
|
eventAggregator.Subscribe(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public BindableCollection<INavigationItem> SidebarItems { get; set; }
|
public BindableCollection<INavigationItem> SidebarItems { get; set; }
|
||||||
@ -66,53 +69,6 @@ namespace Artemis.UI.Screens.Sidebar
|
|||||||
Task.Run(() => SelectSidebarItem(SidebarItems[1]));
|
Task.Run(() => SelectSidebarItem(SidebarItems[1]));
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task SelectSidebarItem(INavigationItem sidebarItem)
|
|
||||||
{
|
|
||||||
// A module was selected if the dictionary contains the selected item
|
|
||||||
if (SidebarModules.ContainsKey(sidebarItem))
|
|
||||||
await ActivateModule(sidebarItem);
|
|
||||||
else if (sidebarItem is FirstLevelNavigationItem navigationItem)
|
|
||||||
{
|
|
||||||
if (navigationItem.Label == "Home")
|
|
||||||
await ActivateViewModel<HomeViewModel>();
|
|
||||||
else if (navigationItem.Label == "News")
|
|
||||||
await ActivateViewModel<NewsViewModel>();
|
|
||||||
else if (navigationItem.Label == "Workshop")
|
|
||||||
await ActivateViewModel<WorkshopViewModel>();
|
|
||||||
else if (navigationItem.Label == "Surface Editor")
|
|
||||||
await ActivateViewModel<SurfaceEditorViewModel>();
|
|
||||||
else if (navigationItem.Label == "Settings")
|
|
||||||
await ActivateViewModel<SettingsViewModel>();
|
|
||||||
}
|
|
||||||
else if (await CloseCurrentItem())
|
|
||||||
SelectedItem = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task<bool> CloseCurrentItem()
|
|
||||||
{
|
|
||||||
if (SelectedItem == null)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
var canClose = await SelectedItem.CanCloseAsync();
|
|
||||||
if (!canClose)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
SelectedItem.Close();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task ActivateViewModel<T>()
|
|
||||||
{
|
|
||||||
if (await CloseCurrentItem())
|
|
||||||
SelectedItem = (IScreen) _kernel.Get<T>();
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task ActivateModule(INavigationItem sidebarItem)
|
|
||||||
{
|
|
||||||
if (await CloseCurrentItem())
|
|
||||||
SelectedItem = SidebarModules.ContainsKey(sidebarItem) ? _moduleVmFactory.Create(SidebarModules[sidebarItem]) : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReSharper disable once UnusedMember.Global - Called by view
|
// ReSharper disable once UnusedMember.Global - Called by view
|
||||||
public async Task SelectItem(WillSelectNavigationItemEventArgs args)
|
public async Task SelectItem(WillSelectNavigationItemEventArgs args)
|
||||||
{
|
{
|
||||||
@ -151,6 +107,56 @@ namespace Artemis.UI.Screens.Sidebar
|
|||||||
SidebarModules.Remove(existing.Key);
|
SidebarModules.Remove(existing.Key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task SelectSidebarItem(INavigationItem sidebarItem)
|
||||||
|
{
|
||||||
|
// A module was selected if the dictionary contains the selected item
|
||||||
|
if (SidebarModules.ContainsKey(sidebarItem))
|
||||||
|
await ActivateModule(sidebarItem);
|
||||||
|
else if (sidebarItem is FirstLevelNavigationItem navigationItem)
|
||||||
|
await ActivateViewModel(navigationItem.Label);
|
||||||
|
else if (await CloseCurrentItem())
|
||||||
|
SelectedItem = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<bool> CloseCurrentItem()
|
||||||
|
{
|
||||||
|
if (SelectedItem == null)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
var canClose = await SelectedItem.CanCloseAsync();
|
||||||
|
if (!canClose)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
SelectedItem.Close();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task ActivateViewModel(string label)
|
||||||
|
{
|
||||||
|
if (label == "Home")
|
||||||
|
await ActivateViewModel<HomeViewModel>();
|
||||||
|
else if (label == "News")
|
||||||
|
await ActivateViewModel<NewsViewModel>();
|
||||||
|
else if (label == "Workshop")
|
||||||
|
await ActivateViewModel<WorkshopViewModel>();
|
||||||
|
else if (label == "Surface Editor")
|
||||||
|
await ActivateViewModel<SurfaceEditorViewModel>();
|
||||||
|
else if (label == "Settings")
|
||||||
|
await ActivateViewModel<SettingsViewModel>();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task ActivateViewModel<T>()
|
||||||
|
{
|
||||||
|
if (await CloseCurrentItem())
|
||||||
|
SelectedItem = (IScreen) _kernel.Get<T>();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task ActivateModule(INavigationItem sidebarItem)
|
||||||
|
{
|
||||||
|
if (await CloseCurrentItem())
|
||||||
|
SelectedItem = SidebarModules.ContainsKey(sidebarItem) ? _moduleVmFactory.Create(SidebarModules[sidebarItem]) : null;
|
||||||
|
}
|
||||||
|
|
||||||
#region Event handlers
|
#region Event handlers
|
||||||
|
|
||||||
private void PluginServiceOnPluginEnabled(object sender, PluginEventArgs e)
|
private void PluginServiceOnPluginEnabled(object sender, PluginEventArgs e)
|
||||||
@ -165,6 +171,11 @@ namespace Artemis.UI.Screens.Sidebar
|
|||||||
RemoveModule(module);
|
RemoveModule(module);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Handle(RequestSelectSidebarItemEvent message)
|
||||||
|
{
|
||||||
|
Execute.OnUIThread(async () => await ActivateViewModel(message.Label));
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -20,9 +20,29 @@
|
|||||||
DoubleClickCommand="{s:Action TrayBringToForeground}">
|
DoubleClickCommand="{s:Action TrayBringToForeground}">
|
||||||
<tb:TaskbarIcon.ContextMenu>
|
<tb:TaskbarIcon.ContextMenu>
|
||||||
<ContextMenu>
|
<ContextMenu>
|
||||||
<MenuItem Header="Bring to foreground" Command="{s:Action TrayBringToForeground}">
|
<MenuItem Header="Home" Command="{s:Action TrayActivateSidebarItem}" CommandParameter="Home">
|
||||||
<MenuItem.Icon>
|
<MenuItem.Icon>
|
||||||
<materialDesign:PackIcon Kind="ArrangeBringToFront" />
|
<materialDesign:PackIcon Kind="Home" />
|
||||||
|
</MenuItem.Icon>
|
||||||
|
</MenuItem>
|
||||||
|
<MenuItem Header="News" Command="{s:Action TrayActivateSidebarItem}" CommandParameter="News">
|
||||||
|
<MenuItem.Icon>
|
||||||
|
<materialDesign:PackIcon Kind="Newspaper" />
|
||||||
|
</MenuItem.Icon>
|
||||||
|
</MenuItem>
|
||||||
|
<MenuItem Header="Workshop" Command="{s:Action TrayActivateSidebarItem}" CommandParameter="Workshop">
|
||||||
|
<MenuItem.Icon>
|
||||||
|
<materialDesign:PackIcon Kind="TestTube" />
|
||||||
|
</MenuItem.Icon>
|
||||||
|
</MenuItem>
|
||||||
|
<MenuItem Header="Surface Editor" Command="{s:Action TrayActivateSidebarItem}" CommandParameter="Surface Editor">
|
||||||
|
<MenuItem.Icon>
|
||||||
|
<materialDesign:PackIcon Kind="Edit" />
|
||||||
|
</MenuItem.Icon>
|
||||||
|
</MenuItem>
|
||||||
|
<MenuItem Header="Settings" Command="{s:Action TrayActivateSidebarItem}" CommandParameter="Settings">
|
||||||
|
<MenuItem.Icon>
|
||||||
|
<materialDesign:PackIcon Kind="Settings" />
|
||||||
</MenuItem.Icon>
|
</MenuItem.Icon>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<Separator />
|
<Separator />
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
using System.Windows;
|
using System.Windows;
|
||||||
using Artemis.Core.Services;
|
using Artemis.Core.Services;
|
||||||
using Artemis.Core.Services.Interfaces;
|
using Artemis.Core.Services.Interfaces;
|
||||||
|
using Artemis.UI.Events;
|
||||||
using Artemis.UI.Screens.Splash;
|
using Artemis.UI.Screens.Splash;
|
||||||
using Ninject;
|
using Ninject;
|
||||||
using Stylet;
|
using Stylet;
|
||||||
@ -9,15 +10,16 @@ namespace Artemis.UI.Screens
|
|||||||
{
|
{
|
||||||
public class TrayViewModel : Screen
|
public class TrayViewModel : Screen
|
||||||
{
|
{
|
||||||
private readonly ICoreService _coreService;
|
|
||||||
private readonly IKernel _kernel;
|
private readonly IKernel _kernel;
|
||||||
private readonly IWindowManager _windowManager;
|
private readonly IWindowManager _windowManager;
|
||||||
|
private readonly IEventAggregator _eventAggregator;
|
||||||
|
private SplashViewModel _splashViewModel;
|
||||||
|
|
||||||
public TrayViewModel(IKernel kernel, IWindowManager windowManager, ICoreService coreService, ISettingsService settingsService)
|
public TrayViewModel(IKernel kernel, IWindowManager windowManager, IEventAggregator eventAggregator, ICoreService coreService, ISettingsService settingsService)
|
||||||
{
|
{
|
||||||
_kernel = kernel;
|
_kernel = kernel;
|
||||||
_windowManager = windowManager;
|
_windowManager = windowManager;
|
||||||
_coreService = coreService;
|
_eventAggregator = eventAggregator;
|
||||||
CanShowRootViewModel = true;
|
CanShowRootViewModel = true;
|
||||||
|
|
||||||
var autoRunning = Bootstrapper.StartupArguments.Contains("-autorun");
|
var autoRunning = Bootstrapper.StartupArguments.Contains("-autorun");
|
||||||
@ -25,7 +27,7 @@ namespace Artemis.UI.Screens
|
|||||||
if (!autoRunning || showOnAutoRun)
|
if (!autoRunning || showOnAutoRun)
|
||||||
{
|
{
|
||||||
ShowSplashScreen();
|
ShowSplashScreen();
|
||||||
_coreService.Initialized += (sender, args) => TrayBringToForeground();
|
coreService.Initialized += (sender, args) => TrayBringToForeground();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,16 +37,24 @@ namespace Artemis.UI.Screens
|
|||||||
{
|
{
|
||||||
if (!CanShowRootViewModel)
|
if (!CanShowRootViewModel)
|
||||||
return;
|
return;
|
||||||
CanShowRootViewModel = false;
|
|
||||||
|
|
||||||
|
CanShowRootViewModel = false;
|
||||||
Execute.OnUIThread(() =>
|
Execute.OnUIThread(() =>
|
||||||
{
|
{
|
||||||
|
_splashViewModel?.RequestClose();
|
||||||
|
_splashViewModel = null;
|
||||||
var rootViewModel = _kernel.Get<RootViewModel>();
|
var rootViewModel = _kernel.Get<RootViewModel>();
|
||||||
rootViewModel.Closed += RootViewModelOnClosed;
|
rootViewModel.Closed += RootViewModelOnClosed;
|
||||||
_windowManager.ShowWindow(rootViewModel);
|
_windowManager.ShowWindow(rootViewModel);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void TrayActivateSidebarItem(string sidebarItem)
|
||||||
|
{
|
||||||
|
TrayBringToForeground();
|
||||||
|
_eventAggregator.Publish(new RequestSelectSidebarItemEvent(sidebarItem));
|
||||||
|
}
|
||||||
|
|
||||||
public void TrayExit()
|
public void TrayExit()
|
||||||
{
|
{
|
||||||
Application.Current.Shutdown();
|
Application.Current.Shutdown();
|
||||||
@ -54,8 +64,8 @@ namespace Artemis.UI.Screens
|
|||||||
{
|
{
|
||||||
Execute.OnUIThread(() =>
|
Execute.OnUIThread(() =>
|
||||||
{
|
{
|
||||||
var splashViewModel = _kernel.Get<SplashViewModel>();
|
_splashViewModel = _kernel.Get<SplashViewModel>();
|
||||||
_windowManager.ShowWindow(splashViewModel);
|
_windowManager.ShowWindow(_splashViewModel);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -5,13 +5,19 @@ VisualStudioVersion = 16.0.28729.10
|
|||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Artemis.UI", "Artemis.UI\Artemis.UI.csproj", "{46B74153-77CF-4489-BDF9-D53FDB1F7ACB}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Artemis.UI", "Artemis.UI\Artemis.UI.csproj", "{46B74153-77CF-4489-BDF9-D53FDB1F7ACB}"
|
||||||
ProjectSection(ProjectDependencies) = postProject
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
{07678400-2FE1-4C6E-A8D4-4F9F3C0630EA} = {07678400-2FE1-4C6E-A8D4-4F9F3C0630EA}
|
||||||
{AB80F106-5444-46AA-A255-F765DD2F04F1} = {AB80F106-5444-46AA-A255-F765DD2F04F1}
|
{AB80F106-5444-46AA-A255-F765DD2F04F1} = {AB80F106-5444-46AA-A255-F765DD2F04F1}
|
||||||
{8DC7960F-6DDF-4007-A155-17E124F39374} = {8DC7960F-6DDF-4007-A155-17E124F39374}
|
{8DC7960F-6DDF-4007-A155-17E124F39374} = {8DC7960F-6DDF-4007-A155-17E124F39374}
|
||||||
{DCF7C321-95DC-4507-BB61-A7C5356E58EC} = {DCF7C321-95DC-4507-BB61-A7C5356E58EC}
|
{DCF7C321-95DC-4507-BB61-A7C5356E58EC} = {DCF7C321-95DC-4507-BB61-A7C5356E58EC}
|
||||||
{E592F239-FAA0-4840-9C85-46E5867D06D5} = {E592F239-FAA0-4840-9C85-46E5867D06D5}
|
{E592F239-FAA0-4840-9C85-46E5867D06D5} = {E592F239-FAA0-4840-9C85-46E5867D06D5}
|
||||||
|
{36C10640-A31F-4DEE-9F0E-9B9E3F12753D} = {36C10640-A31F-4DEE-9F0E-9B9E3F12753D}
|
||||||
{0F288A66-6EB0-4589-8595-E33A3A3EAEA2} = {0F288A66-6EB0-4589-8595-E33A3A3EAEA2}
|
{0F288A66-6EB0-4589-8595-E33A3A3EAEA2} = {0F288A66-6EB0-4589-8595-E33A3A3EAEA2}
|
||||||
|
{A46F278A-FC2C-4342-8455-994D957DDA03} = {A46F278A-FC2C-4342-8455-994D957DDA03}
|
||||||
|
{26902C94-3EBC-4132-B7F0-FFCAB8E150DA} = {26902C94-3EBC-4132-B7F0-FFCAB8E150DA}
|
||||||
{7F4C7AB0-4C9B-452D-AFED-34544C903DEF} = {7F4C7AB0-4C9B-452D-AFED-34544C903DEF}
|
{7F4C7AB0-4C9B-452D-AFED-34544C903DEF} = {7F4C7AB0-4C9B-452D-AFED-34544C903DEF}
|
||||||
{235A45C7-24AD-4F47-B9D4-CD67E610A04D} = {235A45C7-24AD-4F47-B9D4-CD67E610A04D}
|
{235A45C7-24AD-4F47-B9D4-CD67E610A04D} = {235A45C7-24AD-4F47-B9D4-CD67E610A04D}
|
||||||
|
{D004FEC9-0CF8-4828-B620-95DBA73201A3} = {D004FEC9-0CF8-4828-B620-95DBA73201A3}
|
||||||
|
{FA5815D3-EA87-4A64-AD6C-A5AE96C61F29} = {FA5815D3-EA87-4A64-AD6C-A5AE96C61F29}
|
||||||
{C6BDB6D9-062D-4C28-A280-F3BD6197F07F} = {C6BDB6D9-062D-4C28-A280-F3BD6197F07F}
|
{C6BDB6D9-062D-4C28-A280-F3BD6197F07F} = {C6BDB6D9-062D-4C28-A280-F3BD6197F07F}
|
||||||
{A779B2F8-C253-4C4B-8634-6EB8F594E96D} = {A779B2F8-C253-4C4B-8634-6EB8F594E96D}
|
{A779B2F8-C253-4C4B-8634-6EB8F594E96D} = {A779B2F8-C253-4C4B-8634-6EB8F594E96D}
|
||||||
EndProjectSection
|
EndProjectSection
|
||||||
|
|||||||
@ -0,0 +1,14 @@
|
|||||||
|
namespace Artemis.Plugins.Devices.WS281X.Settings
|
||||||
|
{
|
||||||
|
public class DeviceDefinition
|
||||||
|
{
|
||||||
|
public DeviceDefinitionType Type { get; set; }
|
||||||
|
public string Port { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum DeviceDefinitionType
|
||||||
|
{
|
||||||
|
Arduino,
|
||||||
|
Bitwizard
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,17 +1,18 @@
|
|||||||
using System;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Text;
|
|
||||||
using Artemis.Core.Plugins.Abstract;
|
using Artemis.Core.Plugins.Abstract;
|
||||||
using Artemis.Core.Plugins.Abstract.ViewModels;
|
using Artemis.Core.Plugins.Abstract.ViewModels;
|
||||||
|
using Artemis.Core.Plugins.Models;
|
||||||
|
using Artemis.Plugins.Devices.WS281X.Settings;
|
||||||
|
|
||||||
namespace Artemis.Plugins.Devices.WS281X.ViewModels
|
namespace Artemis.Plugins.Devices.WS281X.ViewModels
|
||||||
{
|
{
|
||||||
public class WS281XConfigurationViewModel : PluginConfigurationViewModel
|
public class WS281XConfigurationViewModel : PluginConfigurationViewModel
|
||||||
{
|
{
|
||||||
public WS281XConfigurationViewModel(Plugin plugin) : base(plugin)
|
private PluginSetting<List<DeviceDefinition>> _definitions;
|
||||||
|
|
||||||
|
public WS281XConfigurationViewModel(Plugin plugin, PluginSettings settings) : base(plugin)
|
||||||
{
|
{
|
||||||
var WS281XInstance = RGB.NET.Devices.WS281X.WS281XDeviceProvider.Instance;
|
_definitions = settings.GetSetting<List<DeviceDefinition>>("DeviceDefinitions");
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,26 +1,47 @@
|
|||||||
using Artemis.Core.Plugins.Abstract;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Artemis.Core.Plugins.Abstract;
|
||||||
using Artemis.Core.Plugins.Abstract.ViewModels;
|
using Artemis.Core.Plugins.Abstract.ViewModels;
|
||||||
using Artemis.Core.Plugins.Models;
|
using Artemis.Core.Plugins.Models;
|
||||||
using Artemis.Core.Services.Interfaces;
|
using Artemis.Core.Services.Interfaces;
|
||||||
|
using Artemis.Plugins.Devices.WS281X.Settings;
|
||||||
using Artemis.Plugins.Devices.WS281X.ViewModels;
|
using Artemis.Plugins.Devices.WS281X.ViewModels;
|
||||||
|
using RGB.NET.Devices.WS281X.Arduino;
|
||||||
|
using RGB.NET.Devices.WS281X.Bitwizard;
|
||||||
|
|
||||||
namespace Artemis.Plugins.Devices.WS281X
|
namespace Artemis.Plugins.Devices.WS281X
|
||||||
{
|
{
|
||||||
// ReSharper disable once UnusedMember.Global
|
// ReSharper disable once UnusedMember.Global
|
||||||
public class WS281XDeviceProvider : DeviceProvider
|
public class WS281XDeviceProvider : DeviceProvider
|
||||||
{
|
{
|
||||||
|
public PluginSettings Settings { get; }
|
||||||
private readonly IRgbService _rgbService;
|
private readonly IRgbService _rgbService;
|
||||||
|
|
||||||
public WS281XDeviceProvider(PluginInfo pluginInfo, IRgbService rgbService) : base(pluginInfo, RGB.NET.Devices.WS281X.WS281XDeviceProvider.Instance)
|
public WS281XDeviceProvider(PluginInfo pluginInfo, IRgbService rgbService, PluginSettings settings) : base(pluginInfo, RGB.NET.Devices.WS281X.WS281XDeviceProvider.Instance)
|
||||||
{
|
{
|
||||||
|
Settings = settings;
|
||||||
_rgbService = rgbService;
|
_rgbService = rgbService;
|
||||||
HasConfigurationViewModel = true;
|
HasConfigurationViewModel = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void EnablePlugin()
|
public override void EnablePlugin()
|
||||||
{
|
{
|
||||||
// TODO: Load from configuration
|
var definitions = Settings.GetSetting<List<DeviceDefinition>>("DeviceDefinitions");
|
||||||
//RGB.NET.Devices.WS281X.WS281XDeviceProvider.Instance.AddDeviceDefinition();
|
foreach (var deviceDefinition in definitions.Value)
|
||||||
|
{
|
||||||
|
switch (deviceDefinition.Type)
|
||||||
|
{
|
||||||
|
case DeviceDefinitionType.Arduino:
|
||||||
|
RGB.NET.Devices.WS281X.WS281XDeviceProvider.Instance.AddDeviceDefinition(new ArduinoWS281XDeviceDefinition(deviceDefinition.Port));
|
||||||
|
break;
|
||||||
|
case DeviceDefinitionType.Bitwizard:
|
||||||
|
RGB.NET.Devices.WS281X.WS281XDeviceProvider.Instance.AddDeviceDefinition(new BitwizardWS281XDeviceDefinition(deviceDefinition.Port));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new ArgumentOutOfRangeException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_rgbService.AddDeviceProvider(RgbDeviceProvider);
|
_rgbService.AddDeviceProvider(RgbDeviceProvider);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,7 +59,7 @@ namespace Artemis.Plugins.Devices.WS281X
|
|||||||
|
|
||||||
public override PluginConfigurationViewModel GetConfigurationViewModel()
|
public override PluginConfigurationViewModel GetConfigurationViewModel()
|
||||||
{
|
{
|
||||||
return new WS281XConfigurationViewModel(this);
|
return new WS281XConfigurationViewModel(this, Settings);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user