mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-13 05:48:35 +00:00
Added layer unsaved changes warning
This commit is contained in:
parent
317b1cb369
commit
526bc2661a
@ -289,7 +289,8 @@
|
||||
<Compile Include="Events\ToggleEnabled.cs" />
|
||||
<Compile Include="Events\ActiveEffectChanged.cs" />
|
||||
<Compile Include="Events\ChangeBitmap.cs" />
|
||||
<Compile Include="InjectionFactories\IProfileEditorViewModelFactory.cs" />
|
||||
<Compile Include="InjectionFactories\ILayerEditorVmFactory.cs" />
|
||||
<Compile Include="InjectionFactories\IProfileEditorVmFactory.cs" />
|
||||
<Compile Include="ItemBehaviours\BindableSelectedItemBehavior.cs" />
|
||||
<Compile Include="DeviceProviders\Corsair\CorsairRGB.cs" />
|
||||
<Compile Include="DeviceProviders\KeyboardProvider.cs" />
|
||||
|
||||
12
Artemis/Artemis/InjectionFactories/ILayerEditorVmFactory.cs
Normal file
12
Artemis/Artemis/InjectionFactories/ILayerEditorVmFactory.cs
Normal file
@ -0,0 +1,12 @@
|
||||
using Artemis.Models.Interfaces;
|
||||
using Artemis.Models.Profiles;
|
||||
using Artemis.Services;
|
||||
using Artemis.ViewModels.Profiles;
|
||||
|
||||
namespace Artemis.InjectionFactories
|
||||
{
|
||||
public interface ILayerEditorVmFactory
|
||||
{
|
||||
LayerEditorViewModel CreateLayerEditorVm(IGameDataModel gameDataModel, LayerModel layer);
|
||||
}
|
||||
}
|
||||
@ -1,12 +0,0 @@
|
||||
using Artemis.Managers;
|
||||
using Artemis.Models;
|
||||
using Artemis.ViewModels.Profiles;
|
||||
using Caliburn.Micro;
|
||||
|
||||
namespace Artemis.InjectionFactories
|
||||
{
|
||||
public interface IProfileEditorViewModelFactory
|
||||
{
|
||||
ProfileEditorViewModel CreateProfileEditorViewModel(IEventAggregator events, MainManager mainManager, GameModel gameModel, string lastProfile);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,13 @@
|
||||
using Artemis.Managers;
|
||||
using Artemis.Models;
|
||||
using Artemis.ViewModels.Profiles;
|
||||
using Caliburn.Micro;
|
||||
|
||||
namespace Artemis.InjectionFactories
|
||||
{
|
||||
public interface IProfileEditorVmFactory
|
||||
{
|
||||
ProfileEditorViewModel CreateProfileEditorVm(IEventAggregator events, MainManager mainManager,
|
||||
GameModel gameModel, string lastProfile);
|
||||
}
|
||||
}
|
||||
@ -16,7 +16,8 @@ namespace Artemis.InjectionModules
|
||||
{
|
||||
// ViewModels
|
||||
Bind<IScreen>().To<ShellViewModel>().InSingletonScope();
|
||||
Bind<IProfileEditorViewModelFactory>().ToFactory();
|
||||
Bind<IProfileEditorVmFactory>().ToFactory();
|
||||
Bind<ILayerEditorVmFactory>().ToFactory();
|
||||
Bind<ProfileViewModel>().ToSelf();
|
||||
|
||||
Bind<BaseViewModel>().To<WelcomeViewModel>().InSingletonScope();
|
||||
|
||||
@ -11,7 +11,7 @@ namespace Artemis.Modules.Games.CounterStrike
|
||||
{
|
||||
public sealed class CounterStrikeViewModel : GameViewModel
|
||||
{
|
||||
public CounterStrikeViewModel(MainManager main, IEventAggregator events, IProfileEditorViewModelFactory pFactory)
|
||||
public CounterStrikeViewModel(MainManager main, IEventAggregator events, IProfileEditorVmFactory pFactory)
|
||||
: base(main, new CounterStrikeModel(main, new CounterStrikeSettings()), events, pFactory)
|
||||
{
|
||||
DisplayName = "CS:GO";
|
||||
|
||||
@ -11,7 +11,7 @@ namespace Artemis.Modules.Games.Dota2
|
||||
{
|
||||
public sealed class Dota2ViewModel : GameViewModel
|
||||
{
|
||||
public Dota2ViewModel(MainManager main, IEventAggregator events, IProfileEditorViewModelFactory pFactory)
|
||||
public Dota2ViewModel(MainManager main, IEventAggregator events, IProfileEditorVmFactory pFactory)
|
||||
: base(main, new Dota2Model(main, new Dota2Settings()), events, pFactory)
|
||||
{
|
||||
DisplayName = "Dota 2";
|
||||
|
||||
@ -12,7 +12,7 @@ namespace Artemis.Modules.Games.Overwatch
|
||||
{
|
||||
public sealed class OverwatchViewModel : GameViewModel
|
||||
{
|
||||
public OverwatchViewModel(MainManager main, IEventAggregator events, IProfileEditorViewModelFactory pFactory)
|
||||
public OverwatchViewModel(MainManager main, IEventAggregator events, IProfileEditorVmFactory pFactory)
|
||||
: base(main, new OverwatchModel(events, main, new OverwatchSettings()), events, pFactory)
|
||||
{
|
||||
DisplayName = "Overwatch";
|
||||
|
||||
@ -13,7 +13,7 @@ namespace Artemis.Modules.Games.RocketLeague
|
||||
{
|
||||
private string _versionText;
|
||||
|
||||
public RocketLeagueViewModel(MainManager main, IEventAggregator events, IProfileEditorViewModelFactory pFactory)
|
||||
public RocketLeagueViewModel(MainManager main, IEventAggregator events, IProfileEditorVmFactory pFactory)
|
||||
: base(main, new RocketLeagueModel(main, new RocketLeagueSettings()), events, pFactory)
|
||||
{
|
||||
DisplayName = "Rocket League";
|
||||
|
||||
@ -7,7 +7,7 @@ namespace Artemis.Modules.Games.TheDivision
|
||||
{
|
||||
public sealed class TheDivisionViewModel : GameViewModel
|
||||
{
|
||||
public TheDivisionViewModel(MainManager main, IEventAggregator events, IProfileEditorViewModelFactory pFactory)
|
||||
public TheDivisionViewModel(MainManager main, IEventAggregator events, IProfileEditorVmFactory pFactory)
|
||||
: base(main, new TheDivisionModel(main, new TheDivisionSettings()), events, pFactory)
|
||||
{
|
||||
DisplayName = "The Division";
|
||||
|
||||
@ -13,7 +13,7 @@ namespace Artemis.Modules.Games.Witcher3
|
||||
{
|
||||
public sealed class Witcher3ViewModel : GameViewModel
|
||||
{
|
||||
public Witcher3ViewModel(MainManager main, IEventAggregator events, IProfileEditorViewModelFactory pFactory)
|
||||
public Witcher3ViewModel(MainManager main, IEventAggregator events, IProfileEditorVmFactory pFactory)
|
||||
: base(main, new Witcher3Model(main, new Witcher3Settings()), events, pFactory)
|
||||
{
|
||||
DisplayName = "The Witcher 3";
|
||||
|
||||
@ -60,6 +60,21 @@ namespace Artemis.Utilities
|
||||
}
|
||||
}
|
||||
|
||||
public static string Serialize<T>(T source)
|
||||
{
|
||||
// Don't serialize a null object, simply return the default for that object
|
||||
if (ReferenceEquals(source, null))
|
||||
return null;
|
||||
|
||||
var serializer = new XmlSerializer(typeof(T));
|
||||
var stream = new StringWriter();
|
||||
using (stream)
|
||||
{
|
||||
serializer.Serialize(stream, source);
|
||||
return stream.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
public static object GetPropertyValue(object o, string path)
|
||||
{
|
||||
var propertyNames = path.Split('.');
|
||||
|
||||
@ -16,7 +16,7 @@ namespace Artemis.ViewModels.Abstract
|
||||
private GameSettings _gameSettings;
|
||||
|
||||
protected GameViewModel(MainManager mainManager, GameModel gameModel, IEventAggregator events,
|
||||
IProfileEditorViewModelFactory pFactory)
|
||||
IProfileEditorVmFactory pFactory)
|
||||
{
|
||||
MainManager = mainManager;
|
||||
GameModel = gameModel;
|
||||
@ -24,7 +24,7 @@ namespace Artemis.ViewModels.Abstract
|
||||
PFactory = pFactory;
|
||||
GameSettings = gameModel.Settings;
|
||||
|
||||
ProfileEditor = PFactory.CreateProfileEditorViewModel(Events, mainManager, gameModel,
|
||||
ProfileEditor = PFactory.CreateProfileEditorVm(Events, mainManager, gameModel,
|
||||
GameSettings.LastProfile);
|
||||
GameModel.Profile = ProfileEditor.SelectedProfile;
|
||||
ProfileEditor.PropertyChanged += ProfileUpdater;
|
||||
@ -41,7 +41,7 @@ namespace Artemis.ViewModels.Abstract
|
||||
public MetroDialogService DialogService { get; set; }
|
||||
|
||||
public IEventAggregator Events { get; set; }
|
||||
public IProfileEditorViewModelFactory PFactory { get; set; }
|
||||
public IProfileEditorVmFactory PFactory { get; set; }
|
||||
|
||||
public ProfileEditorViewModel ProfileEditor { get; set; }
|
||||
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
using System.ComponentModel;
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Xml.Serialization;
|
||||
using Artemis.Models.Interfaces;
|
||||
using Artemis.Models.Profiles;
|
||||
using Artemis.Models.Profiles.Properties;
|
||||
@ -8,6 +10,7 @@ using Artemis.Services;
|
||||
using Artemis.Utilities;
|
||||
using Artemis.ViewModels.Profiles.Properties;
|
||||
using Caliburn.Micro;
|
||||
using Newtonsoft.Json;
|
||||
using Ninject;
|
||||
|
||||
namespace Artemis.ViewModels.Profiles
|
||||
@ -26,6 +29,8 @@ namespace Artemis.ViewModels.Profiles
|
||||
_gameDataModel = gameDataModel;
|
||||
|
||||
Layer = layer;
|
||||
ProposedLayer = GeneralHelpers.Clone(layer);
|
||||
|
||||
if (Layer.Properties == null)
|
||||
Layer.SetupProperties();
|
||||
|
||||
@ -38,6 +43,8 @@ namespace Artemis.ViewModels.Profiles
|
||||
PreSelect();
|
||||
}
|
||||
|
||||
public bool ModelChanged { get; set; }
|
||||
|
||||
[Inject]
|
||||
public MetroDialogService DialogService { get; set; }
|
||||
|
||||
@ -69,17 +76,6 @@ namespace Artemis.ViewModels.Profiles
|
||||
}
|
||||
}
|
||||
|
||||
public LayerPropertiesModel ProposedProperties
|
||||
{
|
||||
get { return _proposedProperties; }
|
||||
set
|
||||
{
|
||||
if (Equals(value, _proposedProperties)) return;
|
||||
_proposedProperties = value;
|
||||
NotifyOfPropertyChange(() => ProposedProperties);
|
||||
}
|
||||
}
|
||||
|
||||
public LayerType LayerType
|
||||
{
|
||||
get { return _layerType; }
|
||||
@ -102,17 +98,15 @@ namespace Artemis.ViewModels.Profiles
|
||||
}
|
||||
}
|
||||
|
||||
public bool KeyboardGridIsVisible => Layer.LayerType == LayerType.Keyboard;
|
||||
public bool GifGridIsVisible => Layer.LayerType == LayerType.KeyboardGif;
|
||||
public bool KeyboardGridIsVisible => ProposedLayer.LayerType == LayerType.Keyboard;
|
||||
public bool GifGridIsVisible => ProposedLayer.LayerType == LayerType.KeyboardGif;
|
||||
|
||||
public void PreSelect()
|
||||
{
|
||||
LayerType = Layer.LayerType;
|
||||
LayerType = ProposedLayer.LayerType;
|
||||
|
||||
if (LayerType == LayerType.Folder && !(LayerPropertiesViewModel is FolderPropertiesViewModel))
|
||||
LayerPropertiesViewModel = new FolderPropertiesViewModel(_gameDataModel, Layer.Properties);
|
||||
|
||||
ProposedProperties = GeneralHelpers.Clone(Layer.Properties);
|
||||
LayerPropertiesViewModel = new FolderPropertiesViewModel(_gameDataModel, ProposedLayer.Properties);
|
||||
}
|
||||
|
||||
private void PropertiesViewModelHandler(object sender, PropertyChangedEventArgs e)
|
||||
@ -124,14 +118,14 @@ namespace Artemis.ViewModels.Profiles
|
||||
var oldBrush = LayerPropertiesViewModel?.GetAppliedProperties().Brush;
|
||||
|
||||
// Update the model
|
||||
if (Layer.LayerType != LayerType)
|
||||
if (ProposedLayer.LayerType != LayerType)
|
||||
{
|
||||
Layer.LayerType = LayerType;
|
||||
Layer.SetupProperties();
|
||||
ProposedLayer.LayerType = LayerType;
|
||||
ProposedLayer.SetupProperties();
|
||||
}
|
||||
|
||||
if (oldBrush != null)
|
||||
Layer.Properties.Brush = oldBrush;
|
||||
ProposedLayer.Properties.Brush = oldBrush;
|
||||
|
||||
// Update the KeyboardPropertiesViewModel if it's being used
|
||||
var model = LayerPropertiesViewModel as KeyboardPropertiesViewModel;
|
||||
@ -142,17 +136,17 @@ namespace Artemis.ViewModels.Profiles
|
||||
if ((LayerType == LayerType.Keyboard || LayerType == LayerType.KeyboardGif) &&
|
||||
!(LayerPropertiesViewModel is KeyboardPropertiesViewModel))
|
||||
{
|
||||
LayerPropertiesViewModel = new KeyboardPropertiesViewModel(_gameDataModel, Layer.Properties)
|
||||
LayerPropertiesViewModel = new KeyboardPropertiesViewModel(_gameDataModel, ProposedLayer.Properties)
|
||||
{
|
||||
IsGif = LayerType == LayerType.KeyboardGif
|
||||
};
|
||||
}
|
||||
else if (LayerType == LayerType.Mouse && !(LayerPropertiesViewModel is MousePropertiesViewModel))
|
||||
LayerPropertiesViewModel = new MousePropertiesViewModel(_gameDataModel, Layer.Properties);
|
||||
LayerPropertiesViewModel = new MousePropertiesViewModel(_gameDataModel, ProposedLayer.Properties);
|
||||
else if (LayerType == LayerType.Headset && !(LayerPropertiesViewModel is HeadsetPropertiesViewModel))
|
||||
LayerPropertiesViewModel = new HeadsetPropertiesViewModel(_gameDataModel, Layer.Properties);
|
||||
LayerPropertiesViewModel = new HeadsetPropertiesViewModel(_gameDataModel, ProposedLayer.Properties);
|
||||
else if (LayerType == LayerType.Folder && !(LayerPropertiesViewModel is FolderPropertiesViewModel))
|
||||
LayerPropertiesViewModel = new FolderPropertiesViewModel(_gameDataModel, Layer.Properties);
|
||||
LayerPropertiesViewModel = new FolderPropertiesViewModel(_gameDataModel, ProposedLayer.Properties);
|
||||
|
||||
NotifyOfPropertyChange(() => LayerPropertiesViewModel);
|
||||
}
|
||||
@ -165,11 +159,17 @@ namespace Artemis.ViewModels.Profiles
|
||||
|
||||
public void Apply()
|
||||
{
|
||||
Layer.Name = ProposedLayer.Name;
|
||||
Layer.LayerType = ProposedLayer.LayerType;
|
||||
|
||||
if (LayerPropertiesViewModel != null)
|
||||
Layer.Properties = LayerPropertiesViewModel.GetAppliedProperties();
|
||||
Layer.Properties.Conditions.Clear();
|
||||
foreach (var conditionViewModel in LayerConditionVms)
|
||||
{
|
||||
|
||||
Layer.Properties.Conditions.Add(conditionViewModel.LayerConditionModel);
|
||||
}
|
||||
|
||||
if (Layer.LayerType != LayerType.KeyboardGif)
|
||||
return; // Don't bother checking for a GIF path unless the type is GIF
|
||||
@ -183,5 +183,29 @@ namespace Artemis.ViewModels.Profiles
|
||||
LayerConditionVms.Remove(layerConditionViewModel);
|
||||
Layer.Properties.Conditions.Remove(layerConditionModel);
|
||||
}
|
||||
|
||||
public override async void CanClose(Action<bool> callback)
|
||||
{
|
||||
// Create a fake layer and apply the properties to it
|
||||
var fakeLayer = GeneralHelpers.Clone(ProposedLayer);
|
||||
if (LayerPropertiesViewModel != null)
|
||||
fakeLayer.Properties = LayerPropertiesViewModel.GetAppliedProperties();
|
||||
fakeLayer.Properties.Conditions.Clear();
|
||||
foreach (var conditionViewModel in LayerConditionVms)
|
||||
fakeLayer.Properties.Conditions.Add(conditionViewModel.LayerConditionModel);
|
||||
|
||||
|
||||
var fake = GeneralHelpers.Serialize(fakeLayer);
|
||||
var real = GeneralHelpers.Serialize(Layer);
|
||||
|
||||
if (fake.Equals(real))
|
||||
{
|
||||
callback(true);
|
||||
return;
|
||||
}
|
||||
|
||||
var close = await DialogService.ShowQuestionMessageBox("Unsaved changes", "Do you want to discard your changes?");
|
||||
callback(close.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -12,6 +12,7 @@ using System.Windows.Media.Imaging;
|
||||
using Artemis.DAL;
|
||||
using Artemis.DeviceProviders;
|
||||
using Artemis.Events;
|
||||
using Artemis.InjectionFactories;
|
||||
using Artemis.Managers;
|
||||
using Artemis.Models;
|
||||
using Artemis.Models.Profiles;
|
||||
@ -33,18 +34,20 @@ namespace Artemis.ViewModels.Profiles
|
||||
public sealed class ProfileEditorViewModel : Screen, IHandle<ActiveKeyboardChanged>, IDropTarget
|
||||
{
|
||||
private readonly GameModel _gameModel;
|
||||
private readonly ILayerEditorVmFactory _layerEditorVmFactory;
|
||||
private readonly MainManager _mainManager;
|
||||
private LayerEditorViewModel _editorVm;
|
||||
private ImageSource _keyboardPreview;
|
||||
private BindableCollection<LayerModel> _layers;
|
||||
private BindableCollection<ProfileModel> _profiles;
|
||||
private ProfileModel _selectedProfile;
|
||||
|
||||
public ProfileEditorViewModel(IEventAggregator events, MainManager mainManager, GameModel gameModel,
|
||||
ProfileViewModel profileViewModel, MetroDialogService dialogService, string lastProfile)
|
||||
ProfileViewModel profileViewModel, MetroDialogService dialogService, string lastProfile,
|
||||
ILayerEditorVmFactory layerEditorVmFactory)
|
||||
{
|
||||
_mainManager = mainManager;
|
||||
_gameModel = gameModel;
|
||||
_layerEditorVmFactory = layerEditorVmFactory;
|
||||
|
||||
Profiles = new BindableCollection<ProfileModel>();
|
||||
Layers = new BindableCollection<LayerModel>();
|
||||
@ -263,7 +266,7 @@ namespace Artemis.ViewModels.Profiles
|
||||
public void EditLayer(LayerModel layer)
|
||||
{
|
||||
IWindowManager manager = new WindowManager();
|
||||
_editorVm = new LayerEditorViewModel(_gameModel.GameDataModel, layer);
|
||||
var editorVm = _layerEditorVmFactory.CreateLayerEditorVm(_gameModel.GameDataModel, layer);
|
||||
dynamic settings = new ExpandoObject();
|
||||
var iconImage = new Image
|
||||
{
|
||||
@ -278,7 +281,7 @@ namespace Artemis.ViewModels.Profiles
|
||||
settings.Title = "Artemis | Edit " + layer.Name;
|
||||
settings.Icon = bitmap;
|
||||
|
||||
manager.ShowDialog(_editorVm, null, settings);
|
||||
manager.ShowDialog(editorVm, null, settings);
|
||||
|
||||
// If the layer was a folder, but isn't anymore, assign it's children to it's parent.
|
||||
if (layer.LayerType != LayerType.Folder && layer.Children.Any())
|
||||
|
||||
@ -45,7 +45,7 @@
|
||||
<!-- Layer name -->
|
||||
<TextBlock Grid.Row="1" Grid.Column="0" Margin="10,12" FontSize="13.333" Text="Name:"
|
||||
VerticalAlignment="Center" Height="18" />
|
||||
<TextBox Grid.Row="1" Grid.Column="1" x:Name="Name" Margin="10" Text="{Binding Path=Layer.Name}" />
|
||||
<TextBox Grid.Row="1" Grid.Column="1" x:Name="Name" Margin="10" Text="{Binding Path=ProposedLayer.Name}" />
|
||||
|
||||
<!-- Layer type -->
|
||||
<TextBlock Grid.Row="1" Grid.Column="2" Margin="10,12" FontSize="13.333" Text="Type:"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user