mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-13 05:48:35 +00:00
Added dialog system
Added surface delete
This commit is contained in:
parent
5cdde6e402
commit
ce383468ea
@ -1,6 +1,5 @@
|
||||
using System.Threading.Tasks;
|
||||
using Artemis.Storage.Entities;
|
||||
using Artemis.Storage.Repositories;
|
||||
using Artemis.Storage.Repositories.Interfaces;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
@ -8,6 +7,7 @@ namespace Artemis.Core.Plugins.Models
|
||||
{
|
||||
public class PluginSetting<T>
|
||||
{
|
||||
// ReSharper disable once NotAccessedField.Local
|
||||
private readonly PluginInfo _pluginInfo;
|
||||
private readonly PluginSettingEntity _pluginSettingEntity;
|
||||
private readonly IPluginSettingRepository _pluginSettingRepository;
|
||||
@ -50,6 +50,9 @@ namespace Artemis.Core.Plugins.Models
|
||||
/// </summary>
|
||||
public void Save()
|
||||
{
|
||||
if (!HasChanged)
|
||||
return;
|
||||
|
||||
_pluginSettingEntity.Value = JsonConvert.SerializeObject(Value);
|
||||
_pluginSettingRepository.Save();
|
||||
}
|
||||
@ -60,6 +63,9 @@ namespace Artemis.Core.Plugins.Models
|
||||
/// <returns></returns>
|
||||
public async Task SaveAsync()
|
||||
{
|
||||
if (!HasChanged)
|
||||
return;
|
||||
|
||||
_pluginSettingEntity.Value = JsonConvert.SerializeObject(Value);
|
||||
await _pluginSettingRepository.SaveAsync();
|
||||
}
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Artemis.Storage.Entities;
|
||||
using Artemis.Storage.Repositories;
|
||||
using Artemis.Storage.Repositories.Interfaces;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
@ -28,7 +27,7 @@ namespace Artemis.Core.Plugins.Models
|
||||
var settingEntity = new PluginSettingEntity {Name = name, PluginGuid = _pluginInfo.Guid, Value = JsonConvert.SerializeObject(defaultValue)};
|
||||
_pluginSettingRepository.Add(settingEntity);
|
||||
_pluginSettingRepository.Save();
|
||||
|
||||
|
||||
_settingEntities.Add(name, settingEntity);
|
||||
return new PluginSetting<T>(_pluginInfo, _pluginSettingRepository, _settingEntities[name]);
|
||||
}
|
||||
|
||||
@ -122,10 +122,11 @@ namespace Artemis.Core.Services.Storage
|
||||
|
||||
lock (_surfaceConfigurations)
|
||||
{
|
||||
var entity = surfaceConfiguration.SurfaceEntity;
|
||||
surfaceConfiguration.Destroy();
|
||||
_surfaceConfigurations.Remove(surfaceConfiguration);
|
||||
|
||||
_surfaceRepository.Remove(surfaceConfiguration.SurfaceEntity);
|
||||
_surfaceRepository.Remove(entity);
|
||||
_surfaceRepository.Save();
|
||||
}
|
||||
}
|
||||
|
||||
@ -69,6 +69,9 @@
|
||||
<Reference Include="ControlzEx, Version=3.0.2.4, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\ControlzEx.3.0.2.4\lib\net462\ControlzEx.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="FluentValidation, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7de548da2fbae0f0, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\FluentValidation.8.5.0\lib\net45\FluentValidation.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Humanizer, Version=2.6.0.0, Culture=neutral, PublicKeyToken=979442b78dfc278e, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Humanizer.Core.2.6.2\lib\netstandard2.0\Humanizer.dll</HintPath>
|
||||
</Reference>
|
||||
@ -123,6 +126,10 @@
|
||||
<HintPath>..\packages\Stylet.1.3.0\lib\net45\Stylet.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.ComponentModel.Annotations, Version=4.2.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.ComponentModel.Annotations.4.6.0\lib\net461\System.ComponentModel.Annotations.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.ComponentModel.DataAnnotations" />
|
||||
<Reference Include="System.Configuration" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.ValueTuple, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
@ -148,6 +155,7 @@
|
||||
<Compile Include="Adorners\BoundingBoxAdorner.cs" />
|
||||
<Compile Include="Bootstrapper.cs" />
|
||||
<Compile Include="Converters\ColorToSolidColorBrushConverter.cs" />
|
||||
<Compile Include="Converters\NullToImageConverter.cs" />
|
||||
<Compile Include="Converters\NullToVisibilityConverter.cs" />
|
||||
<Compile Include="Extensions\RgbColorExtensions.cs" />
|
||||
<Compile Include="Extensions\RgbRectangleExtensions.cs" />
|
||||
@ -157,14 +165,22 @@
|
||||
<DesignTime>True</DesignTime>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Services\DialogService.cs" />
|
||||
<Compile Include="Services\Interfaces\IDialogService.cs" />
|
||||
<Compile Include="Services\Interfaces\IArtemisUIService.cs" />
|
||||
<Compile Include="Stylet\ArtemisViewManager.cs" />
|
||||
<Compile Include="Stylet\FluentValidationAdapter.cs" />
|
||||
<Compile Include="Stylet\NinjectBootstrapper.cs" />
|
||||
<Compile Include="ViewModels\Controls\ProfileEditor\ProfileDeviceViewModel.cs" />
|
||||
<Compile Include="ViewModels\Controls\ProfileEditor\ProfileLedViewModel.cs" />
|
||||
<Compile Include="ViewModels\Controls\SurfaceEditor\SurfaceLedViewModel.cs" />
|
||||
<Compile Include="ViewModels\Controls\SurfaceEditor\SurfaceDeviceViewModel.cs" />
|
||||
<Compile Include="ViewModels\PanZoomViewModel.cs" />
|
||||
<Compile Include="ViewModels\Dialogs\ConfirmDialogViewModel.cs" />
|
||||
<Compile Include="ViewModels\Dialogs\SurfaceCreateViewModelValidator.cs" />
|
||||
<Compile Include="ViewModels\Dialogs\SurfaceCreateViewModel.cs" />
|
||||
<Compile Include="ViewModels\Utilities\DialogViewModelHost.cs" />
|
||||
<Compile Include="ViewModels\Dialogs\DialogViewModelBase.cs" />
|
||||
<Compile Include="ViewModels\Utilities\PanZoomViewModel.cs" />
|
||||
<Compile Include="ViewModels\Screens\DebugViewModel.cs" />
|
||||
<Compile Include="ViewModels\Screens\SurfaceEditorViewModel.cs" />
|
||||
<Compile Include="ViewModels\Interfaces\IEditorViewModel.cs" />
|
||||
@ -187,6 +203,14 @@
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Page Include="Views\Dialogs\ConfirmDialogView.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="Views\Dialogs\SurfaceCreateView.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="Views\Screens\DebugView.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
|
||||
22
src/Artemis.UI/Converters/NullToImageConverter.cs
Normal file
22
src/Artemis.UI/Converters/NullToImageConverter.cs
Normal file
@ -0,0 +1,22 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Windows;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace Artemis.UI.Converters
|
||||
{
|
||||
public class NullToImageConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
if (value == null)
|
||||
return DependencyProperty.UnsetValue;
|
||||
return value;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
return Binding.DoNothing;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,7 +1,11 @@
|
||||
using Artemis.UI.Services.Interfaces;
|
||||
using Artemis.UI.Stylet;
|
||||
using Artemis.UI.ViewModels.Dialogs;
|
||||
using Artemis.UI.ViewModels.Interfaces;
|
||||
using FluentValidation;
|
||||
using Ninject.Extensions.Conventions;
|
||||
using Ninject.Modules;
|
||||
using Stylet;
|
||||
|
||||
namespace Artemis.UI.Ninject
|
||||
{
|
||||
@ -10,7 +14,7 @@ namespace Artemis.UI.Ninject
|
||||
{
|
||||
public override void Load()
|
||||
{
|
||||
// Bind all built-in viewmodels
|
||||
// Bind all built-in VMs
|
||||
Kernel.Bind(x =>
|
||||
{
|
||||
x.FromThisAssembly()
|
||||
@ -19,6 +23,15 @@ namespace Artemis.UI.Ninject
|
||||
.BindAllInterfaces();
|
||||
});
|
||||
|
||||
// Bind all dialog VMs
|
||||
Kernel.Bind(x =>
|
||||
{
|
||||
x.FromThisAssembly()
|
||||
.SelectAllClasses()
|
||||
.InheritedFrom<DialogViewModelBase>()
|
||||
.BindAllBaseClasses();
|
||||
});
|
||||
|
||||
// Bind all UI services as singletons
|
||||
Kernel.Bind(x =>
|
||||
{
|
||||
@ -28,6 +41,16 @@ namespace Artemis.UI.Ninject
|
||||
.BindAllInterfaces()
|
||||
.Configure(c => c.InSingletonScope());
|
||||
});
|
||||
|
||||
// Bind all validators
|
||||
Bind(typeof(IModelValidator<>)).To(typeof(FluentValidationAdapter<>));
|
||||
Kernel.Bind(x =>
|
||||
{
|
||||
x.FromThisAssembly()
|
||||
.SelectAllClasses()
|
||||
.InheritedFrom<IValidator>()
|
||||
.BindAllInterfaces();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
70
src/Artemis.UI/Services/DialogService.cs
Normal file
70
src/Artemis.UI/Services/DialogService.cs
Normal file
@ -0,0 +1,70 @@
|
||||
using System.Threading.Tasks;
|
||||
using Artemis.UI.Services.Interfaces;
|
||||
using Artemis.UI.ViewModels.Dialogs;
|
||||
using MaterialDesignThemes.Wpf;
|
||||
using Ninject;
|
||||
using Ninject.Parameters;
|
||||
using Stylet;
|
||||
|
||||
namespace Artemis.UI.Services
|
||||
{
|
||||
public class DialogService : IDialogService
|
||||
{
|
||||
private readonly IKernel _kernel;
|
||||
private readonly IViewManager _viewManager;
|
||||
|
||||
public DialogService(IKernel kernel, IViewManager viewManager)
|
||||
{
|
||||
_kernel = kernel;
|
||||
_viewManager = viewManager;
|
||||
}
|
||||
|
||||
public async Task<bool> ShowConfirmDialog(string header, string text, string confirmText = "Confirm", string cancelText = "Cancel")
|
||||
{
|
||||
var arguments = new IParameter[]
|
||||
{
|
||||
new ConstructorArgument("header", header),
|
||||
new ConstructorArgument("text", text),
|
||||
new ConstructorArgument("confirmText", confirmText),
|
||||
new ConstructorArgument("cancelText", cancelText),
|
||||
};
|
||||
var result = await ShowDialog<ConfirmDialogViewModel>(arguments);
|
||||
return (bool)result;
|
||||
}
|
||||
|
||||
public async Task<bool> ShowConfirmDialogAt(string identifier, string header, string text, string confirmText = "Confirm", string cancelText = "Cancel")
|
||||
{
|
||||
var arguments = new IParameter[]
|
||||
{
|
||||
new ConstructorArgument("header", header),
|
||||
new ConstructorArgument("text", text),
|
||||
new ConstructorArgument("confirmText", confirmText),
|
||||
new ConstructorArgument("cancelText", cancelText),
|
||||
};
|
||||
var result = await ShowDialogAt<ConfirmDialogViewModel>(identifier, arguments);
|
||||
return (bool) result;
|
||||
}
|
||||
|
||||
public async Task<object> ShowDialog<T>(IParameter[] parameters = null) where T : DialogViewModelBase
|
||||
{
|
||||
var viewModel = parameters != null ? _kernel.Get<T>(parameters) : _kernel.Get<T>();
|
||||
return await ShowDialog(null, viewModel);
|
||||
}
|
||||
|
||||
public async Task<object> ShowDialogAt<T>(string identifier, IParameter[] parameters = null) where T : DialogViewModelBase
|
||||
{
|
||||
var viewModel = parameters != null ? _kernel.Get<T>(parameters) : _kernel.Get<T>();
|
||||
return await ShowDialog(identifier, viewModel);
|
||||
}
|
||||
|
||||
private async Task<object> ShowDialog(string identifier, DialogViewModelBase viewModel)
|
||||
{
|
||||
var view = _viewManager.CreateViewForModel(viewModel);
|
||||
_viewManager.BindViewToModel(view, viewModel);
|
||||
|
||||
if (identifier == null)
|
||||
return await DialogHost.Show(view, viewModel.OnDialogClosed);
|
||||
return await DialogHost.Show(view, identifier, viewModel.OnDialogOpened, viewModel.OnDialogClosed);
|
||||
}
|
||||
}
|
||||
}
|
||||
14
src/Artemis.UI/Services/Interfaces/IDialogService.cs
Normal file
14
src/Artemis.UI/Services/Interfaces/IDialogService.cs
Normal file
@ -0,0 +1,14 @@
|
||||
using System.Threading.Tasks;
|
||||
using Artemis.UI.ViewModels.Dialogs;
|
||||
using Ninject.Parameters;
|
||||
|
||||
namespace Artemis.UI.Services.Interfaces
|
||||
{
|
||||
public interface IDialogService : IArtemisUIService
|
||||
{
|
||||
Task<bool> ShowConfirmDialog(string header, string text, string confirmText = "Confirm", string cancelText = "Cancel");
|
||||
Task<bool> ShowConfirmDialogAt(string identifier, string header, string text, string confirmText = "Confirm", string cancelText = "Cancel");
|
||||
Task<object> ShowDialog<T>(IParameter[] parameters = null) where T : DialogViewModelBase;
|
||||
Task<object> ShowDialogAt<T>(string identifier, IParameter[] parameters = null) where T : DialogViewModelBase;
|
||||
}
|
||||
}
|
||||
42
src/Artemis.UI/Stylet/FluentValidationAdapter.cs
Normal file
42
src/Artemis.UI/Stylet/FluentValidationAdapter.cs
Normal file
@ -0,0 +1,42 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using FluentValidation;
|
||||
using Stylet;
|
||||
|
||||
namespace Artemis.UI.Stylet
|
||||
{
|
||||
public class FluentValidationAdapter<T> : IModelValidator<T>
|
||||
{
|
||||
private readonly IValidator<T> _validator;
|
||||
private T _subject;
|
||||
|
||||
public FluentValidationAdapter(IValidator<T> validator)
|
||||
{
|
||||
_validator = validator;
|
||||
}
|
||||
|
||||
public void Initialize(object subject)
|
||||
{
|
||||
_subject = (T) subject;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<string>> ValidatePropertyAsync(string propertyName)
|
||||
{
|
||||
// If someone's calling us synchronously, and ValidationAsync does not complete synchronously,
|
||||
// we'll deadlock unless we continue on another thread.
|
||||
return (await _validator.ValidateAsync(_subject, CancellationToken.None, propertyName).ConfigureAwait(false))
|
||||
.Errors.Select(x => x.ErrorMessage);
|
||||
}
|
||||
|
||||
public async Task<Dictionary<string, IEnumerable<string>>> ValidateAllPropertiesAsync()
|
||||
{
|
||||
// If someone's calling us synchronously, and ValidationAsync does not complete synchronously,
|
||||
// we'll deadlock unless we continue on another thread.
|
||||
return (await _validator.ValidateAsync(_subject).ConfigureAwait(false))
|
||||
.Errors.GroupBy(x => x.PropertyName)
|
||||
.ToDictionary(x => x.Key, x => x.Select(failure => failure.ErrorMessage));
|
||||
}
|
||||
}
|
||||
}
|
||||
28
src/Artemis.UI/ViewModels/Dialogs/ConfirmDialogViewModel.cs
Normal file
28
src/Artemis.UI/ViewModels/Dialogs/ConfirmDialogViewModel.cs
Normal file
@ -0,0 +1,28 @@
|
||||
namespace Artemis.UI.ViewModels.Dialogs
|
||||
{
|
||||
public class ConfirmDialogViewModel : DialogViewModelBase
|
||||
{
|
||||
public ConfirmDialogViewModel(string header, string text, string confirmText, string cancelText)
|
||||
{
|
||||
Header = header;
|
||||
Text = text;
|
||||
ConfirmText = confirmText;
|
||||
CancelText = cancelText;
|
||||
}
|
||||
|
||||
public string Header { get; }
|
||||
public string Text { get; }
|
||||
public string ConfirmText { get; }
|
||||
public string CancelText { get; }
|
||||
|
||||
public void Confirm()
|
||||
{
|
||||
Session.Close(true);
|
||||
}
|
||||
|
||||
public void Cancel()
|
||||
{
|
||||
Session.Close(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
29
src/Artemis.UI/ViewModels/Dialogs/DialogViewModelBase.cs
Normal file
29
src/Artemis.UI/ViewModels/Dialogs/DialogViewModelBase.cs
Normal file
@ -0,0 +1,29 @@
|
||||
using Artemis.UI.ViewModels.Utilities;
|
||||
using MaterialDesignThemes.Wpf;
|
||||
using Stylet;
|
||||
|
||||
namespace Artemis.UI.ViewModels.Dialogs
|
||||
{
|
||||
public abstract class DialogViewModelBase : ValidatingModelBase
|
||||
{
|
||||
protected DialogViewModelBase(IModelValidator validator) : base(validator)
|
||||
{
|
||||
}
|
||||
|
||||
protected DialogViewModelBase()
|
||||
{
|
||||
}
|
||||
|
||||
public DialogViewModelHost DialogViewModelHost { get; set; }
|
||||
public DialogSession Session { get; private set; }
|
||||
|
||||
public void OnDialogOpened(object sender, DialogOpenedEventArgs e)
|
||||
{
|
||||
Session = e.Session;
|
||||
}
|
||||
|
||||
public virtual void OnDialogClosed(object sender, DialogClosingEventArgs e)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
29
src/Artemis.UI/ViewModels/Dialogs/SurfaceCreateViewModel.cs
Normal file
29
src/Artemis.UI/ViewModels/Dialogs/SurfaceCreateViewModel.cs
Normal file
@ -0,0 +1,29 @@
|
||||
using System.Threading.Tasks;
|
||||
using Stylet;
|
||||
|
||||
namespace Artemis.UI.ViewModels.Dialogs
|
||||
{
|
||||
public class SurfaceCreateViewModel : DialogViewModelBase
|
||||
{
|
||||
public SurfaceCreateViewModel(IModelValidator<SurfaceCreateViewModel> validator) : base(validator)
|
||||
{
|
||||
}
|
||||
|
||||
public string SurfaceName { get; set; }
|
||||
|
||||
public async Task Accept()
|
||||
{
|
||||
await ValidateAsync();
|
||||
|
||||
if (HasErrors)
|
||||
return;
|
||||
|
||||
Session.Close(SurfaceName);
|
||||
}
|
||||
|
||||
public void Cancel()
|
||||
{
|
||||
Session.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
using FluentValidation;
|
||||
|
||||
namespace Artemis.UI.ViewModels.Dialogs
|
||||
{
|
||||
public class SurfaceCreateViewModelValidator : AbstractValidator<SurfaceCreateViewModel>
|
||||
{
|
||||
public SurfaceCreateViewModelValidator()
|
||||
{
|
||||
RuleFor(m => m.SurfaceName).NotEmpty().WithMessage("Layout name may not be empty");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,40 +1,40 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using Artemis.Core.Events;
|
||||
using Artemis.Core.Models.Surface;
|
||||
using Artemis.Core.Services.Interfaces;
|
||||
using Artemis.Core.Services.Storage;
|
||||
using Artemis.UI.Services.Interfaces;
|
||||
using Artemis.UI.ViewModels.Controls.SurfaceEditor;
|
||||
using Artemis.UI.ViewModels.Dialogs;
|
||||
using Artemis.UI.ViewModels.Interfaces;
|
||||
using Artemis.UI.ViewModels.Utilities;
|
||||
using Stylet;
|
||||
|
||||
namespace Artemis.UI.ViewModels.Screens
|
||||
{
|
||||
public class SurfaceEditorViewModel : Screen, ISurfaceEditorViewModel
|
||||
{
|
||||
private readonly IRgbService _rgbService;
|
||||
private readonly IDialogService _dialogService;
|
||||
private readonly ISurfaceService _surfaceService;
|
||||
|
||||
public SurfaceEditorViewModel(IRgbService rgbService, ISurfaceService surfaceService)
|
||||
public SurfaceEditorViewModel(ISurfaceService surfaceService, IDialogService dialogService)
|
||||
{
|
||||
Devices = new ObservableCollection<SurfaceDeviceViewModel>();
|
||||
SurfaceConfigurations = new ObservableCollection<SurfaceConfiguration>();
|
||||
SelectionRectangle = new RectangleGeometry();
|
||||
PanZoomViewModel = new PanZoomViewModel();
|
||||
|
||||
_rgbService = rgbService;
|
||||
_surfaceService = surfaceService;
|
||||
_dialogService = dialogService;
|
||||
}
|
||||
|
||||
public RectangleGeometry SelectionRectangle { get; set; }
|
||||
public ObservableCollection<SurfaceDeviceViewModel> Devices { get; set; }
|
||||
public ObservableCollection<SurfaceConfiguration> SurfaceConfigurations { get; set; }
|
||||
|
||||
public SurfaceConfiguration SelectedSurfaceConfiguration
|
||||
{
|
||||
@ -46,14 +46,10 @@ namespace Artemis.UI.ViewModels.Screens
|
||||
}
|
||||
}
|
||||
|
||||
public ObservableCollection<SurfaceConfiguration> SurfaceConfigurations { get; set; }
|
||||
public string NewConfigurationName { get; set; }
|
||||
|
||||
public PanZoomViewModel PanZoomViewModel { get; set; }
|
||||
|
||||
public string Title => "Surface Editor";
|
||||
|
||||
public SurfaceConfiguration AddSurfaceConfiguration(string name)
|
||||
public SurfaceConfiguration CreateSurfaceConfiguration(string name)
|
||||
{
|
||||
var config = _surfaceService.CreateSurfaceConfiguration(name);
|
||||
Execute.OnUIThread(() => SurfaceConfigurations.Add(config));
|
||||
@ -69,7 +65,7 @@ namespace Artemis.UI.ViewModels.Screens
|
||||
var activeConfig = _surfaceService.ActiveSurfaceConfiguration;
|
||||
if (activeConfig == null)
|
||||
{
|
||||
activeConfig = AddSurfaceConfiguration("Default");
|
||||
activeConfig = CreateSurfaceConfiguration("Default");
|
||||
_surfaceService.SetActiveSurfaceConfiguration(activeConfig);
|
||||
}
|
||||
|
||||
@ -121,15 +117,25 @@ namespace Artemis.UI.ViewModels.Screens
|
||||
|
||||
#region Configuration management
|
||||
|
||||
public void ConfirmationDialogClosing()
|
||||
public async Task DeleteSurfaceConfiguration(SurfaceConfiguration surfaceConfiguration)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(NewConfigurationName))
|
||||
var result = await _dialogService.ShowConfirmDialogAt(
|
||||
"SurfaceListDialogHost",
|
||||
"Delete surface configuration",
|
||||
"Are you sure you want to delete this surface configuration?"
|
||||
);
|
||||
if (result)
|
||||
{
|
||||
var newConfig = AddSurfaceConfiguration(NewConfigurationName);
|
||||
SelectedSurfaceConfiguration = newConfig;
|
||||
SurfaceConfigurations.Remove(surfaceConfiguration);
|
||||
_surfaceService.DeleteSurfaceConfiguration(surfaceConfiguration);
|
||||
}
|
||||
}
|
||||
|
||||
NewConfigurationName = null;
|
||||
public async Task AddSurfaceConfiguration()
|
||||
{
|
||||
var result = await _dialogService.ShowDialogAt<SurfaceCreateViewModel>("SurfaceListDialogHost");
|
||||
if (result is string name)
|
||||
CreateSurfaceConfiguration(name);
|
||||
}
|
||||
|
||||
#endregion
|
||||
@ -274,9 +280,7 @@ namespace Artemis.UI.ViewModels.Screens
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_surfaceService.UpdateSurfaceConfiguration(SelectedSurfaceConfiguration, true);
|
||||
}
|
||||
|
||||
Mouse.OverrideCursor = null;
|
||||
_mouseDragStatus = MouseDragStatus.None;
|
||||
|
||||
28
src/Artemis.UI/ViewModels/Utilities/DialogViewModelHost.cs
Normal file
28
src/Artemis.UI/ViewModels/Utilities/DialogViewModelHost.cs
Normal file
@ -0,0 +1,28 @@
|
||||
using Artemis.UI.ViewModels.Dialogs;
|
||||
using MaterialDesignThemes.Wpf;
|
||||
using Stylet;
|
||||
|
||||
namespace Artemis.UI.ViewModels.Utilities
|
||||
{
|
||||
public class DialogViewModelHost : PropertyChangedBase
|
||||
{
|
||||
private readonly IViewManager _viewManager;
|
||||
|
||||
public DialogViewModelHost(IViewManager viewManager)
|
||||
{
|
||||
_viewManager = viewManager;
|
||||
}
|
||||
public DialogViewModelBase ActiveDialogViewModel { get; set; }
|
||||
public bool IsOpen { get; set; }
|
||||
|
||||
public void OpenDialog(DialogViewModelBase viewModel, string dialogIdentifier)
|
||||
{
|
||||
var view = _viewManager.CreateViewForModel(viewModel);
|
||||
DialogHost.Show(view, dialogIdentifier, viewModel.OnDialogClosed);
|
||||
viewModel.DialogViewModelHost = this;
|
||||
|
||||
ActiveDialogViewModel = viewModel;
|
||||
IsOpen = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,15 +1,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using Stylet;
|
||||
|
||||
namespace Artemis.UI.ViewModels
|
||||
namespace Artemis.UI.ViewModels.Utilities
|
||||
{
|
||||
public class PanZoomViewModel : PropertyChangedBase
|
||||
{
|
||||
@ -1,4 +1,4 @@
|
||||
<UserControl x:Class="Artemis.UI.Views.Controls.ProfileEditor.ProfileDeviceView"
|
||||
<UserControl
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
@ -6,14 +6,18 @@
|
||||
xmlns:s="https://github.com/canton7/Stylet"
|
||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||
xmlns:profileEditor="clr-namespace:Artemis.UI.ViewModels.Controls.ProfileEditor"
|
||||
xmlns:Converters="clr-namespace:Artemis.UI.Converters" x:Class="Artemis.UI.Views.Controls.ProfileEditor.ProfileDeviceView"
|
||||
mc:Ignorable="d"
|
||||
d:DataContext="{d:DesignInstance profileEditor:ProfileDeviceViewModel}"
|
||||
d:DataContext="{d:DesignInstance {x:Type profileEditor:ProfileDeviceViewModel}}"
|
||||
d:DesignHeight="450" d:DesignWidth="800"
|
||||
Cursor="{Binding Cursor}"
|
||||
MouseEnter="{s:Action MouseEnter}"
|
||||
MouseLeave="{s:Action MouseLeave}">
|
||||
<UserControl.Resources>
|
||||
<Converters:NullToImageConverter x:Key="NullToImageConverter"/>
|
||||
</UserControl.Resources>
|
||||
<Grid>
|
||||
<Image Source="{Binding Device.DeviceInfo.Image}" />
|
||||
<Image Source="{Binding Device.DeviceInfo.Image, Converter={StaticResource NullToImageConverter}}" />
|
||||
<ItemsControl ItemsSource="{Binding Leds}">
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
@ -21,7 +25,7 @@
|
||||
</ItemsPanelTemplate>
|
||||
</ItemsControl.ItemsPanel>
|
||||
<ItemsControl.ItemContainerStyle>
|
||||
<Style TargetType="ContentPresenter">
|
||||
<Style TargetType="{x:Type ContentPresenter}">
|
||||
<Setter Property="Canvas.Left" Value="{Binding X}" />
|
||||
<Setter Property="Canvas.Top" Value="{Binding Y}" />
|
||||
</Style>
|
||||
|
||||
@ -1,17 +1,21 @@
|
||||
<UserControl x:Class="Artemis.UI.Views.Controls.ProfileEditor.ProfileLedView"
|
||||
<UserControl
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:profileEditor="clr-namespace:Artemis.UI.ViewModels.Controls.ProfileEditor"
|
||||
xmlns:Converters="clr-namespace:Artemis.UI.Converters" x:Class="Artemis.UI.Views.Controls.ProfileEditor.ProfileLedView"
|
||||
mc:Ignorable="d"
|
||||
d:DataContext="{d:DesignInstance profileEditor:ProfileLedViewModel}"
|
||||
d:DataContext="{d:DesignInstance {x:Type profileEditor:ProfileLedViewModel}}"
|
||||
d:DesignHeight="25" d:DesignWidth="25"
|
||||
ToolTip="{Binding Tooltip}"
|
||||
ToolTipService.IsEnabled="{Binding ColorsEnabled}">
|
||||
<UserControl.Resources>
|
||||
<Converters:NullToImageConverter x:Key="NullToImageConverter"/>
|
||||
</UserControl.Resources>
|
||||
<Grid Width="{Binding Width}" Height="{Binding Height}">
|
||||
<Grid.Background>
|
||||
<ImageBrush AlignmentX="Center" AlignmentY="Center" Stretch="Fill" ImageSource="{Binding Led.Image}" />
|
||||
<ImageBrush AlignmentX="Center" AlignmentY="Center" Stretch="Fill" ImageSource="{Binding Led.Image, Converter={StaticResource NullToImageConverter}}" />
|
||||
</Grid.Background>
|
||||
|
||||
<Path Data="{Binding DisplayGeometry}" ClipToBounds="False" Visibility="{Binding ColorsEnabled, Converter={StaticResource BoolToVisibilityConverter}}">
|
||||
|
||||
@ -15,10 +15,11 @@
|
||||
MouseLeave="{s:Action MouseLeave}"
|
||||
ToolTip="{Binding DeviceConfiguration.Device.DeviceInfo.DeviceName}">
|
||||
<UserControl.Resources>
|
||||
<converters:NullToImageConverter x:Key="NullToImageConverter"/>
|
||||
<converters:NullToVisibilityConverter x:Key="NullToVisibilityConverter" />
|
||||
</UserControl.Resources>
|
||||
<Grid>
|
||||
<Image Source="{Binding DeviceConfiguration.Device.DeviceInfo.Image}" />
|
||||
<Image Source="{Binding DeviceConfiguration.Device.DeviceInfo.Image, Converter={StaticResource NullToImageConverter}}" />
|
||||
|
||||
<Rectangle Fill="{DynamicResource ControlBackgroundBrush}"
|
||||
Stroke="{DynamicResource ControlBorderBrush}"
|
||||
|
||||
@ -1,15 +1,19 @@
|
||||
<UserControl x:Class="Artemis.UI.Views.Controls.SurfaceEditor.SurfaceLedView"
|
||||
<UserControl
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:surfaceEditor="clr-namespace:Artemis.UI.ViewModels.Controls.SurfaceEditor"
|
||||
xmlns:Converters="clr-namespace:Artemis.UI.Converters" x:Class="Artemis.UI.Views.Controls.SurfaceEditor.SurfaceLedView"
|
||||
mc:Ignorable="d"
|
||||
d:DataContext="{d:DesignInstance {x:Type surfaceEditor:SurfaceLedViewModel}}"
|
||||
d:DesignHeight="25" d:DesignWidth="25">
|
||||
<UserControl.Resources>
|
||||
<Converters:NullToImageConverter x:Key="NullToImageConverter"/>
|
||||
</UserControl.Resources>
|
||||
<Grid Width="{Binding Width}" Height="{Binding Height}">
|
||||
<Grid.Background>
|
||||
<ImageBrush AlignmentX="Center" AlignmentY="Center" Stretch="Fill" ImageSource="{Binding Led.Image}" />
|
||||
</Grid.Background>
|
||||
<ImageBrush AlignmentX="Center" AlignmentY="Center" Stretch="Fill" ImageSource="{Binding Led.Image, Converter={StaticResource NullToImageConverter}}" />
|
||||
</Grid.Background>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
22
src/Artemis.UI/Views/Dialogs/ConfirmDialogView.xaml
Normal file
22
src/Artemis.UI/Views/Dialogs/ConfirmDialogView.xaml
Normal file
@ -0,0 +1,22 @@
|
||||
<UserControl x:Class="Artemis.UI.Views.Dialogs.ConfirmDialogView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:Artemis.UI.Views.Dialogs"
|
||||
xmlns:s="https://github.com/canton7/Stylet"
|
||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||
xmlns:dialogs="clr-namespace:Artemis.UI.ViewModels.Dialogs"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="163.274" d:DesignWidth="254.425"
|
||||
d:DataContext="{d:DesignInstance dialogs:ConfirmDialogViewModel}">
|
||||
<StackPanel Margin="16">
|
||||
<TextBlock Style="{StaticResource MaterialDesignTitleTextBlock}" Text="{Binding Header}" TextWrapping="Wrap"/>
|
||||
<TextBlock Style="{StaticResource MaterialDesignBody1TextBlock}" Margin="0 20 0 20" Text="{Binding Text}" TextWrapping="Wrap"/>
|
||||
|
||||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
|
||||
<Button Style="{StaticResource MaterialDesignFlatButton}" IsCancel="True" Margin="0 8 8 0" Command="{s:Action Cancel}" Content="{Binding CancelText}"/>
|
||||
<Button Style="{StaticResource MaterialDesignFlatButton}" IsDefault="True" Margin="0 8 0 0" Command="{s:Action Confirm}" Content="{Binding ConfirmText}"/>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</UserControl>
|
||||
37
src/Artemis.UI/Views/Dialogs/SurfaceCreateView.xaml
Normal file
37
src/Artemis.UI/Views/Dialogs/SurfaceCreateView.xaml
Normal file
@ -0,0 +1,37 @@
|
||||
<UserControl x:Class="Artemis.UI.Views.Dialogs.SurfaceCreateView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:Artemis.UI.Views.Dialogs"
|
||||
xmlns:s="https://github.com/canton7/Stylet"
|
||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="213.053" d:DesignWidth="254.425">
|
||||
<StackPanel Margin="16">
|
||||
<TextBlock>
|
||||
Add a new surface layout
|
||||
</TextBlock>
|
||||
|
||||
<TextBox materialDesign:HintAssist.Hint="Layout name" Margin="0 8 0 16" Style="{StaticResource MaterialDesignFloatingHintTextBox}" Text="{Binding SurfaceName}"/>
|
||||
|
||||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
|
||||
<Button Style="{StaticResource MaterialDesignFlatButton}" IsCancel="True" Margin="0 8 8 0" Command="{s:Action Cancel}">
|
||||
<Button.CommandParameter>
|
||||
<system:Boolean xmlns:system="clr-namespace:System;assembly=mscorlib">
|
||||
False
|
||||
</system:Boolean>
|
||||
</Button.CommandParameter>
|
||||
CANCEL
|
||||
</Button>
|
||||
<Button Style="{StaticResource MaterialDesignFlatButton}" IsDefault="True" Margin="0 8 8 0" Command="{s:Action Accept}">
|
||||
<Button.CommandParameter>
|
||||
<system:Boolean xmlns:system="clr-namespace:System;assembly=mscorlib">
|
||||
True
|
||||
</system:Boolean>
|
||||
</Button.CommandParameter>
|
||||
ACCEPT
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</UserControl>
|
||||
@ -176,37 +176,8 @@
|
||||
</Grid>
|
||||
</materialDesign:Card>
|
||||
|
||||
<materialDesign:Card materialDesign:ShadowAssist.ShadowDepth="Depth1" Grid.Row="2" Grid.Column="1"
|
||||
VerticalAlignment="Stretch" Margin="5,0,0,0">
|
||||
<materialDesign:DialogHost DialogClosing="{s:Action ConfirmationDialogClosing}">
|
||||
<materialDesign:DialogHost.DialogContent>
|
||||
<StackPanel Margin="16">
|
||||
<TextBlock>
|
||||
Add a new surface layout.
|
||||
</TextBlock>
|
||||
<TextBox Margin="0 8 0 0" HorizontalAlignment="Stretch" Text="{Binding NewConfigurationName}" />
|
||||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
|
||||
<Button Style="{StaticResource MaterialDesignFlatButton}" IsCancel="True" Margin="0 8 8 0"
|
||||
Command="materialDesign:DialogHost.CloseDialogCommand">
|
||||
<Button.CommandParameter>
|
||||
<system:Boolean xmlns:system="clr-namespace:System;assembly=mscorlib">
|
||||
False
|
||||
</system:Boolean>
|
||||
</Button.CommandParameter>
|
||||
CANCEL
|
||||
</Button>
|
||||
<Button Style="{StaticResource MaterialDesignFlatButton}" IsDefault="True" Margin="0 8 8 0"
|
||||
Command="materialDesign:DialogHost.CloseDialogCommand">
|
||||
<Button.CommandParameter>
|
||||
<system:Boolean xmlns:system="clr-namespace:System;assembly=mscorlib">
|
||||
True
|
||||
</system:Boolean>
|
||||
</Button.CommandParameter>
|
||||
ACCEPT
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</materialDesign:DialogHost.DialogContent>
|
||||
<materialDesign:Card materialDesign:ShadowAssist.ShadowDepth="Depth1" Grid.Row="2" Grid.Column="1" VerticalAlignment="Stretch" Margin="5,0,0,0">
|
||||
<materialDesign:DialogHost Identifier="SurfaceListDialogHost" CloseOnClickAway="True" UseLayoutRounding="True">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*" />
|
||||
@ -215,32 +186,34 @@
|
||||
<ListBox Grid.Row="0" ItemsSource="{Binding SurfaceConfigurations}" SelectedItem="{Binding SelectedSurfaceConfiguration}">
|
||||
<ListBox.Resources>
|
||||
<DataTemplate DataType="{x:Type models:SurfaceConfiguration}">
|
||||
<TextBlock Text="{Binding Name}" ToolTip="{Binding Name}" />
|
||||
<Grid HorizontalAlignment="Stretch">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="230"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Text="{Binding Name}" ToolTip="{Binding Name}" HorizontalAlignment="Left" VerticalAlignment="Center"/>
|
||||
<Button Grid.Column="1"
|
||||
Command="{s:Action DeleteSurfaceConfiguration}"
|
||||
CommandParameter="{Binding}"
|
||||
Style="{StaticResource MaterialDesignIconForegroundButton}"
|
||||
ToolTip="Delete layout configuration"
|
||||
HorizontalAlignment="Right" >
|
||||
<materialDesign:PackIcon Kind="Trashcan" />
|
||||
</Button>
|
||||
</Grid>
|
||||
|
||||
</DataTemplate>
|
||||
</ListBox.Resources>
|
||||
</ListBox>
|
||||
<materialDesign:PopupBox
|
||||
PopupMode="Click"
|
||||
Grid.Row="0"
|
||||
Style="{StaticResource MaterialDesignMultiFloatingActionPopupBox}"
|
||||
PlacementMode="LeftAndAlignMiddles"
|
||||
UnfurlOrientation="Horizontal"
|
||||
ToolTip="Manage surface layouts"
|
||||
Margin="0 0 10 10"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Bottom">
|
||||
<StackPanel
|
||||
Orientation="Horizontal">
|
||||
<Button ToolTip="Add a new surface layout"
|
||||
Command="{x:Static materialDesign:DialogHost.OpenDialogCommand}">
|
||||
<materialDesign:PackIcon Kind="Add" />
|
||||
</Button>
|
||||
<Button ToolTip="Remove selected surface layout"
|
||||
Command="{x:Static materialDesign:DialogHost.OpenDialogCommand}">
|
||||
<materialDesign:PackIcon Kind="Delete" />
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</materialDesign:PopupBox>
|
||||
<Button Grid.Row="0"
|
||||
Style="{StaticResource MaterialDesignFloatingActionButton}"
|
||||
Command="{s:Action AddSurfaceConfiguration}"
|
||||
Margin="0 0 10 10"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Bottom"
|
||||
ToolTip="Add a new surface layout">
|
||||
<materialDesign:PackIcon Kind="Add" Height="24" Width="24" />
|
||||
</Button>
|
||||
</Grid>
|
||||
</materialDesign:DialogHost>
|
||||
</materialDesign:Card>
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
<packages>
|
||||
<package id="Castle.Core" version="4.4.0" targetFramework="net461" />
|
||||
<package id="ControlzEx" version="3.0.2.4" targetFramework="net472" />
|
||||
<package id="FluentValidation" version="8.5.0" targetFramework="net472" />
|
||||
<package id="Fody" version="5.0.6" targetFramework="net472" developmentDependency="true" />
|
||||
<package id="Humanizer.Core" version="2.6.2" targetFramework="net461" />
|
||||
<package id="MahApps.Metro" version="1.6.5" targetFramework="net472" />
|
||||
@ -21,5 +22,6 @@
|
||||
<package id="SQLitePCLRaw.lib.e_sqlite3.v110_xp" version="1.1.12" targetFramework="net472" />
|
||||
<package id="SQLitePCLRaw.provider.e_sqlite3.net45" version="1.1.12" targetFramework="net472" />
|
||||
<package id="Stylet" version="1.3.0" targetFramework="net472" />
|
||||
<package id="System.ComponentModel.Annotations" version="4.6.0" targetFramework="net472" />
|
||||
<package id="System.ValueTuple" version="4.5.0" targetFramework="net472" />
|
||||
</packages>
|
||||
Loading…
x
Reference in New Issue
Block a user