1
0
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:
SpoinkyNL 2016-06-03 20:59:58 +02:00
parent 317b1cb369
commit 526bc2661a
16 changed files with 111 additions and 54 deletions

View File

@ -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" />

View 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);
}
}

View File

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

View File

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

View File

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

View File

@ -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";

View File

@ -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";

View File

@ -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";

View File

@ -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";

View File

@ -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";

View File

@ -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";

View File

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

View File

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

View File

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

View File

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

View File

@ -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:"