mirror of
https://github.com/Artemis-RGB/Artemis
synced 2026-01-01 02:03:32 +00:00
Memory improvements
Increased Corsair key position accuracy Drastically reduced memory usage
This commit is contained in:
parent
a9194e6906
commit
a982e28615
@ -23,40 +23,28 @@ namespace Artemis.DAL
|
|||||||
private static readonly string ProfileFolder =
|
private static readonly string ProfileFolder =
|
||||||
Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + @"\Artemis\profiles";
|
Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + @"\Artemis\profiles";
|
||||||
|
|
||||||
private static readonly List<ProfileModel> Profiles = new List<ProfileModel>();
|
|
||||||
private static bool _installedDefaults;
|
private static bool _installedDefaults;
|
||||||
|
|
||||||
/// <summary>
|
static ProfileProvider()
|
||||||
/// Get all profiles
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>All profiles</returns>
|
|
||||||
public static List<ProfileModel> GetAll()
|
|
||||||
{
|
{
|
||||||
lock (Profiles)
|
CheckProfiles();
|
||||||
{
|
InstallDefaults();
|
||||||
if (!Profiles.Any())
|
|
||||||
ReadProfiles();
|
|
||||||
|
|
||||||
// Return a new list, this'll make sure removing/updating the retrieved list doesn't
|
|
||||||
// affect the datastore
|
|
||||||
return Profiles.ToList();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
public static List<string> GetProfileNames(KeyboardProvider keyboard, EffectModel effect)
|
||||||
/// Get all profiles matching the provided game
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="game">The game to match</param>
|
|
||||||
/// <param name="keyboard">The keyboard to match</param>
|
|
||||||
/// <returns>All profiles matching the provided game</returns>
|
|
||||||
public static List<ProfileModel> GetAll(EffectModel game, KeyboardProvider keyboard)
|
|
||||||
{
|
{
|
||||||
if (game == null)
|
return ReadProfiles(keyboard.Slug + "/" + effect.Name).Select(p => p.Name).ToList();
|
||||||
throw new ArgumentNullException(nameof(game));
|
}
|
||||||
if (keyboard == null)
|
|
||||||
throw new ArgumentNullException(nameof(keyboard));
|
|
||||||
|
|
||||||
return GetAll().Where(g => g.GameName.Equals(game.Name) && g.KeyboardSlug.Equals(keyboard.Slug)).ToList();
|
public static ProfileModel GetProfile(KeyboardProvider keyboard, EffectModel effect, string name)
|
||||||
|
{
|
||||||
|
return ReadProfiles(keyboard.Slug + "/" + effect.Name).FirstOrDefault(p => p.Name == name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool IsProfileUnique(ProfileModel profileModel)
|
||||||
|
{
|
||||||
|
var existing = ReadProfiles(profileModel.KeyboardSlug + "/" + profileModel.GameName);
|
||||||
|
return existing.Contains(profileModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -69,12 +57,6 @@ namespace Artemis.DAL
|
|||||||
if (prof == null)
|
if (prof == null)
|
||||||
throw new ArgumentNullException(nameof(prof));
|
throw new ArgumentNullException(nameof(prof));
|
||||||
|
|
||||||
lock (Profiles)
|
|
||||||
{
|
|
||||||
if (!Profiles.Contains(prof))
|
|
||||||
Profiles.Add(prof);
|
|
||||||
}
|
|
||||||
|
|
||||||
lock (prof)
|
lock (prof)
|
||||||
{
|
{
|
||||||
// Store the file
|
// Store the file
|
||||||
@ -103,100 +85,30 @@ namespace Artemis.DAL
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ReadProfiles()
|
|
||||||
{
|
|
||||||
CheckProfiles();
|
|
||||||
InstallDefaults();
|
|
||||||
|
|
||||||
lock (Profiles)
|
|
||||||
{
|
|
||||||
Profiles.Clear();
|
|
||||||
|
|
||||||
// Create the directory structure
|
|
||||||
var profilePaths = Directory.GetFiles(ProfileFolder, "*.json", SearchOption.AllDirectories);
|
|
||||||
|
|
||||||
// Parse the JSON files into objects and add them if they are valid
|
|
||||||
foreach (var path in profilePaths)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var prof = LoadProfileIfValid(path);
|
|
||||||
if (prof == null)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Only add unique profiles
|
|
||||||
if (Profiles.Any(p => p.GameName == prof.GameName && p.Name == prof.Name &&
|
|
||||||
p.KeyboardSlug == prof.KeyboardSlug))
|
|
||||||
{
|
|
||||||
Logger.Info("Didn't load duplicate profile: {0}", path);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Profiles.Add(prof);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
Logger.Error("Failed to load profile: {0} - {1}", path, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Unpacks the default profiles into the profile directory
|
/// Renames the profile on the model and filesystem
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private static void InstallDefaults()
|
/// <param name="profile">The profile to rename</param>
|
||||||
|
/// <param name="name">The new name</param>
|
||||||
|
public static void RenameProfile(ProfileModel profile, string name)
|
||||||
{
|
{
|
||||||
// Only install the defaults once per session
|
if (string.IsNullOrEmpty(name))
|
||||||
if (_installedDefaults)
|
|
||||||
return;
|
return;
|
||||||
_installedDefaults = true;
|
|
||||||
|
|
||||||
// Load the ZIP from resources
|
// Remove the old profile
|
||||||
var stream = Assembly.GetExecutingAssembly()
|
DeleteProfile(profile);
|
||||||
.GetManifestResourceStream("Artemis.Resources.Keyboards.default-profiles.zip");
|
|
||||||
|
|
||||||
// Extract it over the old defaults in case one was updated
|
// Update the profile, creating a new file
|
||||||
if (stream == null)
|
profile.Name = name;
|
||||||
return;
|
AddOrUpdate(profile);
|
||||||
var archive = new ZipArchive(stream);
|
|
||||||
archive.ExtractToDirectory(ProfileFolder, true);
|
|
||||||
|
|
||||||
var demoProfiles = Profiles.Where(d => d.Name == "Demo (duplicate to keep changes)");
|
|
||||||
InsertGif(demoProfiles, "GIF", Resources.demo_gif, "demo-gif");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void InsertGif(IEnumerable<ProfileModel> profileModels, string layerName, Bitmap gifFile,
|
public static void DeleteProfile(ProfileModel prof)
|
||||||
string fileName)
|
|
||||||
{
|
{
|
||||||
// Extract the GIF file
|
// Remove the file
|
||||||
var gifDir = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + @"\Artemis\gifs";
|
var path = ProfileFolder + $@"\{prof.KeyboardSlug}\{prof.GameName}\{prof.Name}.json";
|
||||||
Directory.CreateDirectory(gifDir);
|
if (File.Exists(path))
|
||||||
var gifPath = gifDir + $"\\{fileName}.gif";
|
File.Delete(path);
|
||||||
gifFile.Save(gifPath);
|
|
||||||
|
|
||||||
foreach (var profile in profileModels)
|
|
||||||
{
|
|
||||||
var gifLayer = profile.GetLayers().FirstOrDefault(l => l.Name == layerName);
|
|
||||||
if (gifLayer == null)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
((KeyboardPropertiesModel) gifLayer.Properties).GifFile = gifPath;
|
|
||||||
AddOrUpdate(profile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Makes sure the profile directory structure is in order and places default profiles
|
|
||||||
/// </summary>
|
|
||||||
private static void CheckProfiles()
|
|
||||||
{
|
|
||||||
// Create the directory structure
|
|
||||||
if (Directory.Exists(ProfileFolder))
|
|
||||||
return;
|
|
||||||
|
|
||||||
Directory.CreateDirectory(ProfileFolder);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -222,7 +134,7 @@ namespace Artemis.DAL
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Exports the given profile to the provided path in XML
|
/// Exports the given profile to the provided path in JSON
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="prof">The profile to export</param>
|
/// <param name="prof">The profile to export</param>
|
||||||
/// <param name="path">The path to save the profile to</param>
|
/// <param name="path">The path to save the profile to</param>
|
||||||
@ -232,41 +144,102 @@ namespace Artemis.DAL
|
|||||||
File.WriteAllText(path, json);
|
File.WriteAllText(path, json);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
public static void InsertGif(string effectName, string profileName, string layerName, Bitmap gifFile, string fileName)
|
||||||
/// Renames the profile on the model and filesystem
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="profile">The profile to rename</param>
|
|
||||||
/// <param name="name">The new name</param>
|
|
||||||
public static void RenameProfile(ProfileModel profile, string name)
|
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(name))
|
var directories = new DirectoryInfo(ProfileFolder).GetDirectories();
|
||||||
return;
|
var profiles = new List<ProfileModel>();
|
||||||
|
foreach (var directoryInfo in directories)
|
||||||
|
profiles.AddRange(ReadProfiles(directoryInfo.Name + "/effectName").Where(d => d.Name == profileName));
|
||||||
|
|
||||||
// Remove the old profile
|
// Extract the GIF file
|
||||||
DeleteProfile(profile);
|
var gifDir = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + @"\Artemis\gifs";
|
||||||
|
Directory.CreateDirectory(gifDir);
|
||||||
|
var gifPath = gifDir + $"\\{fileName}.gif";
|
||||||
|
gifFile.Save(gifPath);
|
||||||
|
|
||||||
// Update the profile, creating a new file
|
foreach (var profile in profiles)
|
||||||
profile.Name = name;
|
{
|
||||||
AddOrUpdate(profile);
|
var gifLayer = profile.GetLayers().FirstOrDefault(l => l.Name == layerName);
|
||||||
|
if (gifLayer == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
((KeyboardPropertiesModel) gifLayer.Properties).GifFile = gifPath;
|
||||||
|
AddOrUpdate(profile);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void DeleteProfile(ProfileModel prof)
|
private static List<ProfileModel> ReadProfiles(string subDirectory)
|
||||||
{
|
{
|
||||||
// Remove from datastore
|
var profiles = new List<ProfileModel>();
|
||||||
lock (Profiles)
|
var directory = ProfileFolder + "/" + subDirectory;
|
||||||
{
|
if (!Directory.Exists(directory))
|
||||||
// Get the profile from the datastore instead of just the provided value, to be certain it is removed
|
return profiles;
|
||||||
var dsProfile = Profiles.FirstOrDefault(p => p.GameName == prof.GameName &&
|
|
||||||
p.Name == prof.Name &&
|
|
||||||
p.KeyboardSlug == prof.KeyboardSlug);
|
|
||||||
if (dsProfile != null)
|
|
||||||
Profiles.Remove(dsProfile);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove the file
|
// Create the directory structure
|
||||||
var path = ProfileFolder + $@"\{prof.KeyboardSlug}\{prof.GameName}\{prof.Name}.json";
|
var profilePaths = Directory.GetFiles(directory, "*.json", SearchOption.AllDirectories);
|
||||||
if (File.Exists(path))
|
|
||||||
File.Delete(path);
|
// Parse the JSON files into objects and add them if they are valid
|
||||||
|
foreach (var path in profilePaths)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var prof = LoadProfileIfValid(path);
|
||||||
|
if (prof == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Only add unique profiles
|
||||||
|
if (profiles.Any(p => p.GameName == prof.GameName && p.Name == prof.Name &&
|
||||||
|
p.KeyboardSlug == prof.KeyboardSlug))
|
||||||
|
{
|
||||||
|
Logger.Info("Didn't load duplicate profile: {0}", path);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
profiles.Add(prof);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Logger.Error("Failed to load profile: {0} - {1}", path, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return profiles;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Unpacks the default profiles into the profile directory
|
||||||
|
/// </summary>
|
||||||
|
private static void InstallDefaults()
|
||||||
|
{
|
||||||
|
// Only install the defaults once per session
|
||||||
|
if (_installedDefaults)
|
||||||
|
return;
|
||||||
|
_installedDefaults = true;
|
||||||
|
|
||||||
|
// Load the ZIP from resources
|
||||||
|
var stream = Assembly.GetExecutingAssembly()
|
||||||
|
.GetManifestResourceStream("Artemis.Resources.Keyboards.default-profiles.zip");
|
||||||
|
|
||||||
|
// Extract it over the old defaults in case one was updated
|
||||||
|
if (stream == null)
|
||||||
|
return;
|
||||||
|
var archive = new ZipArchive(stream);
|
||||||
|
archive.ExtractToDirectory(ProfileFolder, true);
|
||||||
|
|
||||||
|
|
||||||
|
InsertGif("WindowsProfile", "Demo (duplicate to keep changes)", "GIF", Resources.demo_gif, "demo-gif");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Makes sure the profile directory structure is in order and places default profiles
|
||||||
|
/// </summary>
|
||||||
|
private static void CheckProfiles()
|
||||||
|
{
|
||||||
|
// Create the directory structure
|
||||||
|
if (Directory.Exists(ProfileFolder))
|
||||||
|
return;
|
||||||
|
|
||||||
|
Directory.CreateDirectory(ProfileFolder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -11,6 +11,7 @@ using CUE.NET.Brushes;
|
|||||||
using CUE.NET.Devices.Generic;
|
using CUE.NET.Devices.Generic;
|
||||||
using CUE.NET.Devices.Generic.Enums;
|
using CUE.NET.Devices.Generic.Enums;
|
||||||
using CUE.NET.Devices.Keyboard;
|
using CUE.NET.Devices.Keyboard;
|
||||||
|
using CUE.NET.Helper;
|
||||||
using Ninject.Extensions.Logging;
|
using Ninject.Extensions.Logging;
|
||||||
using Point = System.Drawing.Point;
|
using Point = System.Drawing.Point;
|
||||||
|
|
||||||
@ -103,15 +104,17 @@ namespace Artemis.DeviceProviders.Corsair
|
|||||||
// For STRAFE, stretch the image on row 2.
|
// For STRAFE, stretch the image on row 2.
|
||||||
if (_keyboard.DeviceInfo.Model == "STRAFE RGB")
|
if (_keyboard.DeviceInfo.Model == "STRAFE RGB")
|
||||||
{
|
{
|
||||||
var strafeBitmap = new Bitmap(22, 8);
|
using (var strafeBitmap = new Bitmap(22, 8))
|
||||||
using (var g = Graphics.FromImage(strafeBitmap))
|
|
||||||
{
|
{
|
||||||
g.DrawImage(image, new Point(0, 0));
|
using (var g = Graphics.FromImage(strafeBitmap))
|
||||||
g.DrawImage(image, new Rectangle(0, 3, 22, 7), new Rectangle(0, 2, 22, 7), GraphicsUnit.Pixel);
|
{
|
||||||
}
|
g.DrawImage(image, new Point(0, 0));
|
||||||
|
g.DrawImage(image, new Rectangle(0, 3, 22, 7), new Rectangle(0, 2, 22, 7), GraphicsUnit.Pixel);
|
||||||
|
}
|
||||||
|
|
||||||
image.Dispose();
|
image.Dispose();
|
||||||
image = strafeBitmap;
|
image = strafeBitmap;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_keyboardBrush.Image = image;
|
_keyboardBrush.Image = image;
|
||||||
@ -136,11 +139,11 @@ namespace Artemis.DeviceProviders.Corsair
|
|||||||
// ignored
|
// ignored
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cueLed != null)
|
if (cueLed == null)
|
||||||
return new KeyMatch(keyCode, (int) (cueLed.LedRectangle.X*widthMultiplier),
|
return null;
|
||||||
(int) (cueLed.LedRectangle.Y*heightMultiplier));
|
|
||||||
|
|
||||||
return null;
|
var center = cueLed.LedRectangle.GetCenter();
|
||||||
|
return new KeyMatch(keyCode, (int) (center.X*widthMultiplier),(int) (center.Y*heightMultiplier));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -96,19 +96,21 @@ namespace Artemis.Modules.Games.UnrealTournament
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Load the ZIP from resources
|
// Load the ZIP from resources
|
||||||
var stream = new MemoryStream(Resources.ut_plugin);
|
using (var stream = new MemoryStream(Resources.ut_plugin))
|
||||||
var archive = new ZipArchive(stream);
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
Directory.CreateDirectory(path + @"\UnrealTournament\Plugins\Artemis");
|
var archive = new ZipArchive(stream);
|
||||||
archive.ExtractToDirectory(path + @"\UnrealTournament\Plugins\Artemis", true);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
MainManager.Logger.Error(e, "Failed to install Unreal Tournament plugin in '{0}'", path);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(path + @"\UnrealTournament\Plugins\Artemis");
|
||||||
|
archive.ExtractToDirectory(path + @"\UnrealTournament\Plugins\Artemis", true);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
MainManager.Logger.Error(e, "Failed to install Unreal Tournament plugin in '{0}'", path);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
MainManager.Logger.Info("Installed Unreal Tournament plugin in '{0}'", path);
|
MainManager.Logger.Info("Installed Unreal Tournament plugin in '{0}'", path);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,13 +119,8 @@ namespace Artemis.Modules.Games.UnrealTournament
|
|||||||
var gif = Resources.redeemer;
|
var gif = Resources.redeemer;
|
||||||
if (gif == null)
|
if (gif == null)
|
||||||
return;
|
return;
|
||||||
var utProfiles = ProfileProvider.GetAll()?
|
|
||||||
.Where(p => (p.GameName == "UnrealTournament") && (p.Name == "Default")).ToList();
|
|
||||||
|
|
||||||
if (utProfiles == null || !utProfiles.Any())
|
ProfileProvider.InsertGif("UnrealTournament", "Default", "Redeemer GIF", gif, "redeemer");
|
||||||
return;
|
|
||||||
|
|
||||||
ProfileProvider.InsertGif(utProfiles, "Redeemer GIF", gif, "redeemer");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -66,10 +66,11 @@ namespace Artemis.Modules.Games.Witcher3
|
|||||||
if (_witcherSettings == null)
|
if (_witcherSettings == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var reader = new StreamReader(
|
var reader =
|
||||||
File.Open(_witcherSettings, FileMode.Open, FileAccess.Read, FileShare.ReadWrite));
|
new StreamReader(File.Open(_witcherSettings, FileMode.Open, FileAccess.Read, FileShare.ReadWrite));
|
||||||
var configContent = reader.ReadToEnd();
|
var configContent = reader.ReadToEnd();
|
||||||
reader.Close();
|
reader.Close();
|
||||||
|
reader.Dispose();
|
||||||
|
|
||||||
var signRes = _configRegex.Match(configContent);
|
var signRes = _configRegex.Match(configContent);
|
||||||
var parts = signRes.Value.Split('\n').Skip(1).Select(v => v.Replace("\r", "")).ToList();
|
var parts = signRes.Value.Split('\n').Skip(1).Select(v => v.Replace("\r", "")).ToList();
|
||||||
|
|||||||
@ -53,7 +53,10 @@ namespace Artemis.Profiles.Layers.Types.KeyboardGif
|
|||||||
lock (layer.GifImage)
|
lock (layer.GifImage)
|
||||||
{
|
{
|
||||||
var draw = layer.GifImage.GetNextFrame();
|
var draw = layer.GifImage.GetNextFrame();
|
||||||
c.DrawImage(ImageUtilities.BitmapToBitmapImage(new Bitmap(draw)), rect);
|
using (var drawBitmap = new Bitmap(draw))
|
||||||
|
{
|
||||||
|
c.DrawImage(ImageUtilities.BitmapToBitmapImage(drawBitmap), rect);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -24,7 +24,6 @@ namespace Artemis.Profiles
|
|||||||
{
|
{
|
||||||
Layers = new ChildItemCollection<ProfileModel, LayerModel>(this);
|
Layers = new ChildItemCollection<ProfileModel, LayerModel>(this);
|
||||||
LuaWrapper = new LuaWrapper(this);
|
LuaWrapper = new LuaWrapper(this);
|
||||||
DrawingVisual = new DrawingVisual();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -42,9 +41,6 @@ namespace Artemis.Profiles
|
|||||||
public int Height { get; set; }
|
public int Height { get; set; }
|
||||||
public string LuaScript { get; set; }
|
public string LuaScript { get; set; }
|
||||||
|
|
||||||
[JsonIgnore]
|
|
||||||
public DrawingVisual DrawingVisual { get; set; }
|
|
||||||
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public LuaWrapper LuaWrapper { get; set; }
|
public LuaWrapper LuaWrapper { get; set; }
|
||||||
|
|
||||||
|
|||||||
@ -9,6 +9,7 @@ using Artemis.DeviceProviders;
|
|||||||
|
|
||||||
namespace Artemis.Utilities.Keyboard
|
namespace Artemis.Utilities.Keyboard
|
||||||
{
|
{
|
||||||
|
// TODO: Obsolete
|
||||||
public class KeyboardRectangle
|
public class KeyboardRectangle
|
||||||
{
|
{
|
||||||
private readonly BackgroundWorker _blinkWorker = new BackgroundWorker {WorkerSupportsCancellation = true};
|
private readonly BackgroundWorker _blinkWorker = new BackgroundWorker {WorkerSupportsCancellation = true};
|
||||||
|
|||||||
@ -40,7 +40,7 @@ namespace Artemis.ViewModels.Profiles
|
|||||||
private readonly Timer _saveTimer;
|
private readonly Timer _saveTimer;
|
||||||
private ImageSource _keyboardPreview;
|
private ImageSource _keyboardPreview;
|
||||||
private BindableCollection<LayerModel> _layers;
|
private BindableCollection<LayerModel> _layers;
|
||||||
private BindableCollection<ProfileModel> _profiles;
|
private BindableCollection<string> _profileNames;
|
||||||
private bool _saving;
|
private bool _saving;
|
||||||
private ProfileModel _selectedProfile;
|
private ProfileModel _selectedProfile;
|
||||||
|
|
||||||
@ -51,7 +51,7 @@ namespace Artemis.ViewModels.Profiles
|
|||||||
_gameModel = gameModel;
|
_gameModel = gameModel;
|
||||||
_layerEditorVmFactory = layerEditorVmFactory;
|
_layerEditorVmFactory = layerEditorVmFactory;
|
||||||
|
|
||||||
Profiles = new BindableCollection<ProfileModel>();
|
ProfileNames = new BindableCollection<string>();
|
||||||
Layers = new BindableCollection<LayerModel>();
|
Layers = new BindableCollection<LayerModel>();
|
||||||
ProfileViewModel = profileViewModel;
|
ProfileViewModel = profileViewModel;
|
||||||
DialogService = dialogService;
|
DialogService = dialogService;
|
||||||
@ -76,17 +76,17 @@ namespace Artemis.ViewModels.Profiles
|
|||||||
|
|
||||||
public bool EditorEnabled
|
public bool EditorEnabled
|
||||||
=>
|
=>
|
||||||
SelectedProfile != null && !SelectedProfile.IsDefault &&
|
(SelectedProfile != null) && !SelectedProfile.IsDefault &&
|
||||||
_mainManager.DeviceManager.ActiveKeyboard != null;
|
(_mainManager.DeviceManager.ActiveKeyboard != null);
|
||||||
|
|
||||||
public BindableCollection<ProfileModel> Profiles
|
public BindableCollection<string> ProfileNames
|
||||||
{
|
{
|
||||||
get { return _profiles; }
|
get { return _profileNames; }
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (Equals(value, _profiles)) return;
|
if (Equals(value, _profileNames)) return;
|
||||||
_profiles = value;
|
_profileNames = value;
|
||||||
NotifyOfPropertyChange(() => Profiles);
|
NotifyOfPropertyChange(() => ProfileNames);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -101,6 +101,23 @@ namespace Artemis.ViewModels.Profiles
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string SelectedProfileName
|
||||||
|
{
|
||||||
|
get { return SelectedProfile.Name; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value == SelectedProfile.Name)
|
||||||
|
return;
|
||||||
|
|
||||||
|
SelectedProfile = ProfileProvider.GetProfile(
|
||||||
|
_mainManager.DeviceManager.ActiveKeyboard,
|
||||||
|
_gameModel,
|
||||||
|
value);
|
||||||
|
|
||||||
|
NotifyOfPropertyChange(() => SelectedProfileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public ProfileModel SelectedProfile
|
public ProfileModel SelectedProfile
|
||||||
{
|
{
|
||||||
get { return _selectedProfile; }
|
get { return _selectedProfile; }
|
||||||
@ -126,16 +143,16 @@ namespace Artemis.ViewModels.Profiles
|
|||||||
public PreviewSettings? PreviewSettings => _mainManager.DeviceManager.ActiveKeyboard?.PreviewSettings;
|
public PreviewSettings? PreviewSettings => _mainManager.DeviceManager.ActiveKeyboard?.PreviewSettings;
|
||||||
|
|
||||||
public bool ProfileSelected => SelectedProfile != null;
|
public bool ProfileSelected => SelectedProfile != null;
|
||||||
public bool LayerSelected => SelectedProfile != null && ProfileViewModel.SelectedLayer != null;
|
public bool LayerSelected => (SelectedProfile != null) && (ProfileViewModel.SelectedLayer != null);
|
||||||
|
|
||||||
public void DragOver(IDropInfo dropInfo)
|
public void DragOver(IDropInfo dropInfo)
|
||||||
{
|
{
|
||||||
var source = dropInfo.Data as LayerModel;
|
var source = dropInfo.Data as LayerModel;
|
||||||
var target = dropInfo.TargetItem as LayerModel;
|
var target = dropInfo.TargetItem as LayerModel;
|
||||||
if (source == null || target == null || source == target)
|
if ((source == null) || (target == null) || (source == target))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (dropInfo.InsertPosition == RelativeInsertPosition.TargetItemCenter &&
|
if ((dropInfo.InsertPosition == RelativeInsertPosition.TargetItemCenter) &&
|
||||||
target.LayerType is FolderType)
|
target.LayerType is FolderType)
|
||||||
{
|
{
|
||||||
dropInfo.DropTargetAdorner = typeof(DropTargetMetroHighlightAdorner);
|
dropInfo.DropTargetAdorner = typeof(DropTargetMetroHighlightAdorner);
|
||||||
@ -152,7 +169,7 @@ namespace Artemis.ViewModels.Profiles
|
|||||||
{
|
{
|
||||||
var source = dropInfo.Data as LayerModel;
|
var source = dropInfo.Data as LayerModel;
|
||||||
var target = dropInfo.TargetItem as LayerModel;
|
var target = dropInfo.TargetItem as LayerModel;
|
||||||
if (source == null || target == null || source == target)
|
if ((source == null) || (target == null) || (source == target))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Don't allow a folder to become it's own child, that's just weird
|
// Don't allow a folder to become it's own child, that's just weird
|
||||||
@ -173,7 +190,7 @@ namespace Artemis.ViewModels.Profiles
|
|||||||
parent.FixOrder();
|
parent.FixOrder();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dropInfo.InsertPosition == RelativeInsertPosition.TargetItemCenter &&
|
if ((dropInfo.InsertPosition == RelativeInsertPosition.TargetItemCenter) &&
|
||||||
target.LayerType is FolderType)
|
target.LayerType is FolderType)
|
||||||
{
|
{
|
||||||
// Insert into folder
|
// Insert into folder
|
||||||
@ -185,9 +202,9 @@ namespace Artemis.ViewModels.Profiles
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Insert the source into it's new profile/parent and update the order
|
// Insert the source into it's new profile/parent and update the order
|
||||||
if (dropInfo.InsertPosition == RelativeInsertPosition.AfterTargetItem ||
|
if ((dropInfo.InsertPosition == RelativeInsertPosition.AfterTargetItem) ||
|
||||||
dropInfo.InsertPosition ==
|
(dropInfo.InsertPosition ==
|
||||||
(RelativeInsertPosition.TargetItemCenter | RelativeInsertPosition.AfterTargetItem))
|
(RelativeInsertPosition.TargetItemCenter | RelativeInsertPosition.AfterTargetItem)))
|
||||||
target.InsertAfter(source);
|
target.InsertAfter(source);
|
||||||
else
|
else
|
||||||
target.InsertBefore(source);
|
target.InsertBefore(source);
|
||||||
@ -222,20 +239,34 @@ namespace Artemis.ViewModels.Profiles
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private void LoadProfiles()
|
private void LoadProfiles()
|
||||||
{
|
{
|
||||||
Profiles.Clear();
|
ProfileNames.Clear();
|
||||||
if (_gameModel == null || _mainManager.DeviceManager.ActiveKeyboard == null)
|
if ((_gameModel == null) || (_mainManager.DeviceManager.ActiveKeyboard == null))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Profiles.AddRange(ProfileProvider.GetAll(_gameModel, _mainManager.DeviceManager.ActiveKeyboard));
|
ProfileNames.AddRange(ProfileProvider.GetProfileNames(_mainManager.DeviceManager.ActiveKeyboard, _gameModel));
|
||||||
|
|
||||||
// If a profile name was provided, try to load it
|
// If a profile name was provided, try to load it
|
||||||
ProfileModel lastProfileModel = null;
|
ProfileModel lastProfileModel = null;
|
||||||
if (!string.IsNullOrEmpty(LastProfile))
|
if (!string.IsNullOrEmpty(LastProfile))
|
||||||
lastProfileModel = Profiles.FirstOrDefault(p => p.Name == LastProfile);
|
{
|
||||||
|
lastProfileModel = ProfileProvider.GetProfile(
|
||||||
|
_mainManager.DeviceManager.ActiveKeyboard,
|
||||||
|
_gameModel,
|
||||||
|
LastProfile);
|
||||||
|
}
|
||||||
|
|
||||||
SelectedProfile = lastProfileModel ?? Profiles.FirstOrDefault();
|
if (lastProfileModel != null)
|
||||||
|
SelectedProfile = lastProfileModel;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SelectedProfile = ProfileProvider.GetProfile(
|
||||||
|
_mainManager.DeviceManager.ActiveKeyboard,
|
||||||
|
_gameModel,
|
||||||
|
ProfileNames.FirstOrDefault());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void EditLayerFromDoubleClick()
|
public void EditLayerFromDoubleClick()
|
||||||
{
|
{
|
||||||
if (ProfileViewModel.SelectedLayer?.LayerType is FolderType)
|
if (ProfileViewModel.SelectedLayer?.LayerType is FolderType)
|
||||||
@ -279,7 +310,6 @@ namespace Artemis.ViewModels.Profiles
|
|||||||
|
|
||||||
// If the layer was a folder, but isn't anymore, assign it's children to it's parent.
|
// If the layer was a folder, but isn't anymore, assign it's children to it's parent.
|
||||||
if (!(layer.LayerType is FolderType) && layer.Children.Any())
|
if (!(layer.LayerType is FolderType) && layer.Children.Any())
|
||||||
{
|
|
||||||
while (layer.Children.Any())
|
while (layer.Children.Any())
|
||||||
{
|
{
|
||||||
var child = layer.Children[0];
|
var child = layer.Children[0];
|
||||||
@ -295,7 +325,6 @@ namespace Artemis.ViewModels.Profiles
|
|||||||
layer.Profile.FixOrder();
|
layer.Profile.FixOrder();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
UpdateLayerList(layer);
|
UpdateLayerList(layer);
|
||||||
}
|
}
|
||||||
@ -495,7 +524,7 @@ namespace Artemis.ViewModels.Profiles
|
|||||||
GameName = _gameModel.Name
|
GameName = _gameModel.Name
|
||||||
};
|
};
|
||||||
|
|
||||||
if (ProfileProvider.GetAll().Contains(profile))
|
if (!ProfileProvider.IsProfileUnique(profile))
|
||||||
{
|
{
|
||||||
var overwrite = await DialogService.ShowQuestionMessageBox("Overwrite existing profile",
|
var overwrite = await DialogService.ShowQuestionMessageBox("Overwrite existing profile",
|
||||||
"A profile with this name already exists for this game. Would you like to overwrite it?");
|
"A profile with this name already exists for this game. Would you like to overwrite it?");
|
||||||
@ -517,18 +546,17 @@ namespace Artemis.ViewModels.Profiles
|
|||||||
var name = await DialogService.ShowInputDialog("Rename profile", "Please enter a unique new profile name");
|
var name = await DialogService.ShowInputDialog("Rename profile", "Please enter a unique new profile name");
|
||||||
|
|
||||||
// Null when the user cancelled
|
// Null when the user cancelled
|
||||||
if (string.IsNullOrEmpty(name) || name.Length < 2)
|
if (string.IsNullOrEmpty(name) || (name.Length < 2))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Verify the name
|
// Verify the name
|
||||||
while (ProfileProvider.GetAll().Any(p => p.Name == name && p.GameName == SelectedProfile.GameName &&
|
while (!ProfileProvider.IsProfileUnique(SelectedProfile))
|
||||||
p.KeyboardSlug == SelectedProfile.KeyboardSlug))
|
|
||||||
{
|
{
|
||||||
name =
|
name =
|
||||||
await DialogService.ShowInputDialog("Name already in use", "Please enter a unique new profile name");
|
await DialogService.ShowInputDialog("Name already in use", "Please enter a unique new profile name");
|
||||||
|
|
||||||
// Null when the user cancelled
|
// Null when the user cancelled
|
||||||
if (string.IsNullOrEmpty(name) || name.Length < 2)
|
if (string.IsNullOrEmpty(name) || (name.Length < 2))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -554,7 +582,7 @@ namespace Artemis.ViewModels.Profiles
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// Verify the name
|
// Verify the name
|
||||||
while (ProfileProvider.GetAll().Contains(newProfile))
|
while (!ProfileProvider.IsProfileUnique(newProfile))
|
||||||
{
|
{
|
||||||
newProfile.Name =
|
newProfile.Name =
|
||||||
await DialogService.ShowInputDialog("Name already in use", "Please enter a unique profile name");
|
await DialogService.ShowInputDialog("Name already in use", "Please enter a unique profile name");
|
||||||
@ -567,7 +595,7 @@ namespace Artemis.ViewModels.Profiles
|
|||||||
newProfile.IsDefault = false;
|
newProfile.IsDefault = false;
|
||||||
ProfileProvider.AddOrUpdate(newProfile);
|
ProfileProvider.AddOrUpdate(newProfile);
|
||||||
LoadProfiles();
|
LoadProfiles();
|
||||||
SelectedProfile = Profiles.FirstOrDefault(p => p.Name == newProfile.Name);
|
SelectedProfile = newProfile;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async void DeleteProfile()
|
public async void DeleteProfile()
|
||||||
@ -640,7 +668,7 @@ namespace Artemis.ViewModels.Profiles
|
|||||||
profile.IsDefault = false;
|
profile.IsDefault = false;
|
||||||
|
|
||||||
// Verify the name
|
// Verify the name
|
||||||
while (ProfileProvider.GetAll().Contains(profile))
|
while (!ProfileProvider.IsProfileUnique(profile))
|
||||||
{
|
{
|
||||||
profile.Name = await DialogService.ShowInputDialog("Rename imported profile",
|
profile.Name = await DialogService.ShowInputDialog("Rename imported profile",
|
||||||
"A profile with this name already exists for this game. Please enter a new name");
|
"A profile with this name already exists for this game. Please enter a new name");
|
||||||
@ -653,7 +681,7 @@ namespace Artemis.ViewModels.Profiles
|
|||||||
ProfileProvider.AddOrUpdate(profile);
|
ProfileProvider.AddOrUpdate(profile);
|
||||||
LoadProfiles();
|
LoadProfiles();
|
||||||
|
|
||||||
SelectedProfile = Profiles.FirstOrDefault(p => p.Name == profile.Name);
|
SelectedProfile = profile;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ExportProfile()
|
public void ExportProfile()
|
||||||
@ -711,7 +739,7 @@ namespace Artemis.ViewModels.Profiles
|
|||||||
|
|
||||||
private void ProfileSaveHandler(object sender, ElapsedEventArgs e)
|
private void ProfileSaveHandler(object sender, ElapsedEventArgs e)
|
||||||
{
|
{
|
||||||
if (_saving || SelectedProfile == null)
|
if (_saving || (SelectedProfile == null))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_saving = true;
|
_saving = true;
|
||||||
|
|||||||
@ -56,8 +56,7 @@
|
|||||||
<StackPanel Grid.Column="0" Grid.Row="2">
|
<StackPanel Grid.Column="0" Grid.Row="2">
|
||||||
<StackPanel Orientation="Horizontal" Margin="0,5,0,0">
|
<StackPanel Orientation="Horizontal" Margin="0,5,0,0">
|
||||||
<Label Content="Active profile" />
|
<Label Content="Active profile" />
|
||||||
<ComboBox Width="220" VerticalAlignment="Top" x:Name="Profiles" DisplayMemberPath="Name"
|
<ComboBox Width="220" VerticalAlignment="Top" x:Name="ProfileNames" Margin="5,0,0,0" />
|
||||||
Margin="5,0,0,0" />
|
|
||||||
<Button x:Name="AddProfile" VerticalAlignment="Top" Style="{DynamicResource SquareButtonStyle}"
|
<Button x:Name="AddProfile" VerticalAlignment="Top" Style="{DynamicResource SquareButtonStyle}"
|
||||||
Width="26" Height="26" HorizontalAlignment="Right" Margin="10,0,0,0" ToolTip="Add profile">
|
Width="26" Height="26" HorizontalAlignment="Right" Margin="10,0,0,0" ToolTip="Add profile">
|
||||||
<Button.Content>
|
<Button.Content>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user