diff --git a/src/Artemis.Core/Models/Surface/Device.cs b/src/Artemis.Core/Models/Surface/Device.cs index 79e3d2691..89588da6e 100644 --- a/src/Artemis.Core/Models/Surface/Device.cs +++ b/src/Artemis.Core/Models/Surface/Device.cs @@ -63,12 +63,18 @@ namespace Artemis.Core.Models.Surface set => DeviceEntity.Rotation = value; } + public double Scale + { + get => DeviceEntity.Scale; + set => DeviceEntity.Scale = value; + } + public int ZIndex { get => DeviceEntity.ZIndex; set => DeviceEntity.ZIndex = value; } - + internal void ApplyToEntity() { // Other properties are computed @@ -79,8 +85,10 @@ namespace Artemis.Core.Models.Surface { RgbDevice.Location = new Point(DeviceEntity.X, DeviceEntity.Y); RgbDevice.Rotation = DeviceEntity.Rotation; + RgbDevice.Scale = DeviceEntity.Scale; CalculateRenderProperties(); + OnDeviceUpdated(); } internal void CalculateRenderProperties() @@ -103,10 +111,16 @@ namespace Artemis.Core.Models.Surface path.FillMode = FillMode.Winding; RenderPath = path; } - + public override string ToString() { return $"[{RgbDevice.DeviceInfo.DeviceType}] {RgbDevice.DeviceInfo.DeviceName} - {X}.{Y}.{ZIndex}"; } + + public event EventHandler DeviceUpdated; + protected virtual void OnDeviceUpdated() + { + DeviceUpdated?.Invoke(this, EventArgs.Empty); + } } } \ No newline at end of file diff --git a/src/Artemis.Storage/Entities/Surface/DeviceEntity.cs b/src/Artemis.Storage/Entities/Surface/DeviceEntity.cs index 3175ce23c..e49ab29d1 100644 --- a/src/Artemis.Storage/Entities/Surface/DeviceEntity.cs +++ b/src/Artemis.Storage/Entities/Surface/DeviceEntity.cs @@ -10,6 +10,7 @@ namespace Artemis.Storage.Entities.Surface public double X { get; set; } public double Y { get; set; } public double Rotation { get; set; } + public double Scale { get; set; } public int ZIndex { get; set; } } } \ No newline at end of file diff --git a/src/Artemis.UI/App.xaml b/src/Artemis.UI/App.xaml index c1b40e14f..64de19b04 100644 --- a/src/Artemis.UI/App.xaml +++ b/src/Artemis.UI/App.xaml @@ -17,19 +17,17 @@ - + - - - - + + + + + + + diff --git a/src/Artemis.UI/Artemis.UI.csproj b/src/Artemis.UI/Artemis.UI.csproj index 54f064410..e4736ed25 100644 --- a/src/Artemis.UI/Artemis.UI.csproj +++ b/src/Artemis.UI/Artemis.UI.csproj @@ -170,6 +170,8 @@ + + @@ -245,6 +247,10 @@ Designer MSBuild:Compile + + Designer + MSBuild:Compile + MSBuild:Compile Designer @@ -352,7 +358,18 @@ - + + + + + + + + + + + + diff --git a/src/Artemis.UI/Properties/Resources.Designer.cs b/src/Artemis.UI/Properties/Resources.Designer.cs index 30752e0a5..43833c3a3 100644 --- a/src/Artemis.UI/Properties/Resources.Designer.cs +++ b/src/Artemis.UI/Properties/Resources.Designer.cs @@ -60,6 +60,46 @@ namespace Artemis.UI.Properties { } } + /// + /// Looks up a localized resource of type System.Byte[]. + /// + internal static byte[] aero_rotate_bl { + get { + object obj = ResourceManager.GetObject("aero_rotate_bl", resourceCulture); + return ((byte[])(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Byte[]. + /// + internal static byte[] aero_rotate_br { + get { + object obj = ResourceManager.GetObject("aero_rotate_br", resourceCulture); + return ((byte[])(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Byte[]. + /// + internal static byte[] aero_rotate_tl { + get { + object obj = ResourceManager.GetObject("aero_rotate_tl", resourceCulture); + return ((byte[])(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Byte[]. + /// + internal static byte[] aero_rotate_tr { + get { + object obj = ResourceManager.GetObject("aero_rotate_tr", resourceCulture); + return ((byte[])(obj)); + } + } + /// /// Looks up a localized resource of type System.Byte[]. /// diff --git a/src/Artemis.UI/Properties/Resources.resx b/src/Artemis.UI/Properties/Resources.resx index eac736e2b..224201a95 100644 --- a/src/Artemis.UI/Properties/Resources.resx +++ b/src/Artemis.UI/Properties/Resources.resx @@ -118,6 +118,18 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + ..\Resources\aero_rotate_bl.cur;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + ..\Resources\aero_rotate_br.cur;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + ..\Resources\aero_rotate_tl.cur;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + ..\Resources\aero_rotate_tr.cur;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ..\Resources\bow.svg;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 diff --git a/src/Artemis.UI/Resources/aero_rotate_bl.cur b/src/Artemis.UI/Resources/aero_rotate_bl.cur new file mode 100644 index 000000000..d43d01340 Binary files /dev/null and b/src/Artemis.UI/Resources/aero_rotate_bl.cur differ diff --git a/src/Artemis.UI/Resources/aero_rotate_br.cur b/src/Artemis.UI/Resources/aero_rotate_br.cur new file mode 100644 index 000000000..ab0c1e67c Binary files /dev/null and b/src/Artemis.UI/Resources/aero_rotate_br.cur differ diff --git a/src/Artemis.UI/Resources/aero_rotate_tl.cur b/src/Artemis.UI/Resources/aero_rotate_tl.cur new file mode 100644 index 000000000..3bc159688 Binary files /dev/null and b/src/Artemis.UI/Resources/aero_rotate_tl.cur differ diff --git a/src/Artemis.UI/Resources/aero_rotate_tr.cur b/src/Artemis.UI/Resources/aero_rotate_tr.cur new file mode 100644 index 000000000..8d0e2f055 Binary files /dev/null and b/src/Artemis.UI/Resources/aero_rotate_tr.cur differ diff --git a/src/Artemis.UI/Screens/Shared/PanZoomViewModel.cs b/src/Artemis.UI/Screens/Shared/PanZoomViewModel.cs index cfe69ada9..2b4f564cb 100644 --- a/src/Artemis.UI/Screens/Shared/PanZoomViewModel.cs +++ b/src/Artemis.UI/Screens/Shared/PanZoomViewModel.cs @@ -46,7 +46,6 @@ namespace Artemis.UI.Screens.Shared { if (e.LeftButton == MouseButtonState.Released) { - Mouse.OverrideCursor = Cursors.Arrow; _lastPanPosition = null; return; } diff --git a/src/Artemis.UI/Screens/SurfaceEditor/Dialogs/SurfaceCreateView.xaml b/src/Artemis.UI/Screens/SurfaceEditor/Dialogs/SurfaceCreateView.xaml index ac771e309..0537bec99 100644 --- a/src/Artemis.UI/Screens/SurfaceEditor/Dialogs/SurfaceCreateView.xaml +++ b/src/Artemis.UI/Screens/SurfaceEditor/Dialogs/SurfaceCreateView.xaml @@ -7,7 +7,7 @@ xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" mc:Ignorable="d" d:DesignHeight="213.053" d:DesignWidth="254.425"> - + Add a new surface layout diff --git a/src/Artemis.UI/Screens/SurfaceEditor/Dialogs/SurfaceDeviceConfigView.xaml b/src/Artemis.UI/Screens/SurfaceEditor/Dialogs/SurfaceDeviceConfigView.xaml new file mode 100644 index 000000000..aabe7060d --- /dev/null +++ b/src/Artemis.UI/Screens/SurfaceEditor/Dialogs/SurfaceDeviceConfigView.xaml @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Artemis.UI/Screens/SurfaceEditor/Dialogs/SurfaceDeviceConfigViewModel.cs b/src/Artemis.UI/Screens/SurfaceEditor/Dialogs/SurfaceDeviceConfigViewModel.cs new file mode 100644 index 000000000..b1dc0496a --- /dev/null +++ b/src/Artemis.UI/Screens/SurfaceEditor/Dialogs/SurfaceDeviceConfigViewModel.cs @@ -0,0 +1,49 @@ +using System.Threading.Tasks; +using Artemis.UI.Screens.SurfaceEditor.Visualization; +using Artemis.UI.ViewModels.Dialogs; +using Stylet; + +namespace Artemis.UI.Screens.SurfaceEditor.Dialogs +{ + public class SurfaceDeviceConfigViewModel : DialogViewModelBase + { + public SurfaceDeviceConfigViewModel(SurfaceDeviceViewModel surfaceDeviceViewModel, IModelValidator validator) + : base(validator) + { + SurfaceDeviceViewModel = surfaceDeviceViewModel; + Title = $"{SurfaceDeviceViewModel.Device.RgbDevice.DeviceInfo.DeviceName} - Properties"; + + X = (int) SurfaceDeviceViewModel.Device.X; + Y = (int) SurfaceDeviceViewModel.Device.Y; + Scale = SurfaceDeviceViewModel.Device.Scale; + Rotation = (int) SurfaceDeviceViewModel.Device.Rotation; + } + + public SurfaceDeviceViewModel SurfaceDeviceViewModel { get; } + public string Title { get; set; } + + public int X { get; set; } + public int Y { get; set; } + public double Scale { get; set; } + public int Rotation { get; set; } + + public async Task Accept() + { + await ValidateAsync(); + if (HasErrors) + return; + + SurfaceDeviceViewModel.Device.X = X; + SurfaceDeviceViewModel.Device.Y = Y; + SurfaceDeviceViewModel.Device.Scale = Scale; + SurfaceDeviceViewModel.Device.Rotation = Rotation; + + Session.Close(true); + } + + public async Task Cancel() + { + Session.Close(false); + } + } +} \ No newline at end of file diff --git a/src/Artemis.UI/Screens/SurfaceEditor/Dialogs/SurfaceDeviceConfigViewModelValidator.cs b/src/Artemis.UI/Screens/SurfaceEditor/Dialogs/SurfaceDeviceConfigViewModelValidator.cs new file mode 100644 index 000000000..764bb36db --- /dev/null +++ b/src/Artemis.UI/Screens/SurfaceEditor/Dialogs/SurfaceDeviceConfigViewModelValidator.cs @@ -0,0 +1,19 @@ +using FluentValidation; + +namespace Artemis.UI.Screens.SurfaceEditor.Dialogs +{ + public class SurfaceDeviceConfigViewModelValidator : AbstractValidator + { + public SurfaceDeviceConfigViewModelValidator() + { + RuleFor(m => m.X).GreaterThanOrEqualTo(0).WithMessage("X-coordinate must be 0 or greater"); + + RuleFor(m => m.Y).GreaterThanOrEqualTo(0).WithMessage("Y-coordinate must be 0 or greater"); + + RuleFor(m => m.Scale).GreaterThanOrEqualTo(0.2).WithMessage("Scale must be 0.2 or greater"); + + RuleFor(m => m.Rotation).GreaterThanOrEqualTo(0).WithMessage("Rotation must be 0 or greater"); + RuleFor(m => m.Rotation).LessThanOrEqualTo(359).WithMessage("Rotation must be 359 or less"); + } + } +} \ No newline at end of file diff --git a/src/Artemis.UI/Screens/SurfaceEditor/SurfaceEditorView.xaml b/src/Artemis.UI/Screens/SurfaceEditor/SurfaceEditorView.xaml index 3f241634c..beefdb3ff 100644 --- a/src/Artemis.UI/Screens/SurfaceEditor/SurfaceEditorView.xaml +++ b/src/Artemis.UI/Screens/SurfaceEditor/SurfaceEditorView.xaml @@ -38,14 +38,17 @@ + VerticalAlignment="Stretch" Margin="0,0,5,0" > + MouseMove="{s:Action EditorGridMouseMove}" + Cursor="{Binding Cursor}"> @@ -101,8 +104,8 @@ @@ -110,32 +113,37 @@ + + + - + - + - + - + + + + + + + @@ -179,8 +187,7 @@ - + diff --git a/src/Artemis.UI/Screens/SurfaceEditor/SurfaceEditorViewModel.cs b/src/Artemis.UI/Screens/SurfaceEditor/SurfaceEditorViewModel.cs index ae877afd9..b4621bdea 100644 --- a/src/Artemis.UI/Screens/SurfaceEditor/SurfaceEditorViewModel.cs +++ b/src/Artemis.UI/Screens/SurfaceEditor/SurfaceEditorViewModel.cs @@ -1,19 +1,21 @@ 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.Models.Surface; using Artemis.Core.Plugins.Models; using Artemis.Core.Services; -using Artemis.Core.Services.Storage; using Artemis.Core.Services.Storage.Interfaces; using Artemis.UI.Screens.Shared; using Artemis.UI.Screens.SurfaceEditor.Dialogs; using Artemis.UI.Screens.SurfaceEditor.Visualization; using Artemis.UI.Services.Interfaces; +using Ninject.Parameters; using Stylet; namespace Artemis.UI.Screens.SurfaceEditor @@ -30,6 +32,7 @@ namespace Artemis.UI.Screens.SurfaceEditor SurfaceConfigurations = new ObservableCollection(); SelectionRectangle = new RectangleGeometry(); PanZoomViewModel = new PanZoomViewModel(); + Cursor = null; _surfaceService = surfaceService; _dialogService = dialogService; @@ -41,6 +44,7 @@ namespace Artemis.UI.Screens.SurfaceEditor public RectangleGeometry SelectionRectangle { get; set; } public PanZoomViewModel PanZoomViewModel { get; set; } public PluginSetting SurfaceListWidth { get; set; } + public Cursor Cursor { get; set; } public Surface SelectedSurface { @@ -120,8 +124,8 @@ namespace Artemis.UI.Screens.SurfaceEditor // Sort the devices by ZIndex Execute.OnUIThread(() => { - foreach (var device in Devices.OrderBy(d => d.ZIndex).ToList()) - Devices.Move(Devices.IndexOf(device), device.ZIndex - 1); + foreach (var device in Devices.OrderBy(d => d.Device.ZIndex).ToList()) + Devices.Move(Devices.IndexOf(device), device.Device.ZIndex - 1); }); _surfaceService.SetActiveSurfaceConfiguration(SelectedSurface); @@ -177,7 +181,7 @@ namespace Artemis.UI.Screens.SurfaceEditor for (var i = 0; i < Devices.Count; i++) { var deviceViewModel = Devices[i]; - deviceViewModel.ZIndex = i + 1; + deviceViewModel.Device.ZIndex = i + 1; } } @@ -190,7 +194,7 @@ namespace Artemis.UI.Screens.SurfaceEditor for (var i = 0; i < Devices.Count; i++) { var deviceViewModel = Devices[i]; - deviceViewModel.ZIndex = i + 1; + deviceViewModel.Device.ZIndex = i + 1; } } @@ -200,7 +204,7 @@ namespace Artemis.UI.Screens.SurfaceEditor for (var i = 0; i < Devices.Count; i++) { var deviceViewModel = Devices[i]; - deviceViewModel.ZIndex = i + 1; + deviceViewModel.Device.ZIndex = i + 1; } } @@ -212,10 +216,21 @@ namespace Artemis.UI.Screens.SurfaceEditor for (var i = 0; i < Devices.Count; i++) { var deviceViewModel = Devices[i]; - deviceViewModel.ZIndex = i + 1; + deviceViewModel.Device.ZIndex = i + 1; } } + public async Task ViewProperties(SurfaceDeviceViewModel surfaceDeviceViewModel) + { + var madeChanges = await _dialogService.ShowDialog(new Dictionary + { + {"surfaceDeviceViewModel", surfaceDeviceViewModel} + }); + + if ((bool) madeChanges) + _surfaceService.UpdateSurfaceConfiguration(SelectedSurface, true); + } + #endregion #region Selection @@ -241,6 +256,7 @@ namespace Artemis.UI.Screens.SurfaceEditor // ReSharper disable once UnusedMember.Global - Called from view public void EditorGridMouseMove(object sender, MouseEventArgs e) { + ((Grid) sender).Focus(); // If holding down Ctrl, pan instead of move/select if (IsPanKeyDown()) { @@ -285,12 +301,6 @@ namespace Artemis.UI.Screens.SurfaceEditor _mouseDragStartPoint = position; } - // While dragging always show a hand to avoid cursor flicker - if (_mouseDragStatus == MouseDragStatus.Dragging) - Mouse.OverrideCursor = Cursors.Hand; - else - Mouse.OverrideCursor = Cursors.Arrow; - // Any time dragging starts, start with a new rect SelectionRectangle.Rect = new Rect(); } @@ -311,7 +321,7 @@ namespace Artemis.UI.Screens.SurfaceEditor else _surfaceService.UpdateSurfaceConfiguration(SelectedSurface, true); - Mouse.OverrideCursor = null; + _mouseDragStatus = MouseDragStatus.None; } @@ -353,13 +363,13 @@ namespace Artemis.UI.Screens.SurfaceEditor public void EditorGridKeyDown(object sender, KeyEventArgs e) { if ((e.Key == Key.LeftCtrl || e.Key == Key.RightCtrl) && e.IsDown) - Mouse.OverrideCursor = Cursors.ScrollAll; + Cursor = Cursors.ScrollAll; } public void EditorGridKeyUp(object sender, KeyEventArgs e) { if ((e.Key == Key.LeftCtrl || e.Key == Key.RightCtrl) && e.IsUp) - Mouse.OverrideCursor = null; + Cursor = null; } public void Pan(object sender, MouseEventArgs e) diff --git a/src/Artemis.UI/Screens/SurfaceEditor/Visualization/SurfaceDeviceViewModel.cs b/src/Artemis.UI/Screens/SurfaceEditor/Visualization/SurfaceDeviceViewModel.cs index 8aef9d8d7..3d7d39b5d 100644 --- a/src/Artemis.UI/Screens/SurfaceEditor/Visualization/SurfaceDeviceViewModel.cs +++ b/src/Artemis.UI/Screens/SurfaceEditor/Visualization/SurfaceDeviceViewModel.cs @@ -3,7 +3,10 @@ using System.Collections.Generic; using System.Windows; using System.Windows.Input; using Artemis.Core.Models.Surface; +using PropertyChanged; +using RGB.NET.Core; using Stylet; +using Point = System.Windows.Point; namespace Artemis.UI.Screens.SurfaceEditor.Visualization { @@ -23,52 +26,44 @@ namespace Artemis.UI.Screens.SurfaceEditor.Visualization foreach (var led in Device.RgbDevice) _leds.Add(new SurfaceLedViewModel(led)); } + + Device.DeviceUpdated += DeviceOnDeviceUpdated; + } + + private void DeviceOnDeviceUpdated(object sender, EventArgs e) + { + NotifyOfPropertyChange(() => RgbDeviceRectangle); + NotifyOfPropertyChange(() => Device.RgbDevice); } public Device Device { get; set; } public SelectionStatus SelectionStatus { get; set; } public Cursor Cursor { get; set; } - public double X - { - get => Device.X; - set => Device.X = value; - } - - public double Y - { - get => Device.Y; - set => Device.Y = value; - } - - public int ZIndex - { - get => Device.ZIndex; - set => Device.ZIndex = value; - } + public Rectangle RgbDeviceRectangle => Device.RgbDevice.DeviceRectangle; public IReadOnlyCollection Leds => _leds.AsReadOnly(); public Rect DeviceRectangle => Device.RgbDevice == null ? new Rect() - : new Rect(X, Y, Device.RgbDevice.Size.Width, Device.RgbDevice.Size.Height); + : new Rect(Device.X, Device.Y, Device.RgbDevice.Size.Width, Device.RgbDevice.Size.Height); public void StartMouseDrag(Point mouseStartPosition) { - _dragOffsetX = X - mouseStartPosition.X; - _dragOffsetY = Y - mouseStartPosition.Y; + _dragOffsetX = Device.X - mouseStartPosition.X; + _dragOffsetY = Device.Y - mouseStartPosition.Y; } public void UpdateMouseDrag(Point mousePosition) { var roundedX = Math.Round((mousePosition.X + _dragOffsetX) / 10, 0, MidpointRounding.AwayFromZero) * 10; var roundedY = Math.Round((mousePosition.Y + _dragOffsetY) / 10, 0, MidpointRounding.AwayFromZero) * 10; - X = Math.Max(0, roundedX); - Y = Math.Max(0, roundedY); + Device.X = Math.Max(0, roundedX); + Device.Y = Math.Max(0, roundedY); } // ReSharper disable once UnusedMember.Global - Called from view - public void MouseEnter() + public void MouseEnter(object sender, MouseEventArgs e) { if (SelectionStatus == SelectionStatus.None) { @@ -86,6 +81,25 @@ namespace Artemis.UI.Screens.SurfaceEditor.Visualization Cursor = Cursors.Arrow; } } + + public MouseDevicePosition GetMouseDevicePosition(Point position) + { + if ((new Point(0, 0) - position).LengthSquared < 5) + { + return MouseDevicePosition.TopLeft; + } + + return MouseDevicePosition.Regular; + } + } + + public enum MouseDevicePosition + { + Regular, + TopLeft, + TopRight, + BottomLeft, + BottomRight } public enum SelectionStatus diff --git a/src/Artemis.UI/Services/Dialog/DialogService.cs b/src/Artemis.UI/Services/Dialog/DialogService.cs index 2cedcec8e..7771ef1a1 100644 --- a/src/Artemis.UI/Services/Dialog/DialogService.cs +++ b/src/Artemis.UI/Services/Dialog/DialogService.cs @@ -1,4 +1,7 @@ -using System.Threading.Tasks; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; using Artemis.UI.Screens.Dialogs; using Artemis.UI.Services.Interfaces; using Artemis.UI.ViewModels.Dialogs; @@ -7,7 +10,7 @@ using Ninject; using Ninject.Parameters; using Stylet; -namespace Artemis.UI.Services +namespace Artemis.UI.Services.Dialog { public class DialogService : IDialogService { @@ -46,16 +49,44 @@ namespace Artemis.UI.Services return (bool) result; } - public async Task ShowDialog(IParameter[] parameters = null) where T : DialogViewModelBase + public async Task ShowDialog() where T : DialogViewModelBase { - var viewModel = parameters != null ? _kernel.Get(parameters) : _kernel.Get(); - return await ShowDialog(null, viewModel); + return await ShowDialog("RootDialog", _kernel.Get()); } - public async Task ShowDialogAt(string identifier, IParameter[] parameters = null) where T : DialogViewModelBase + public Task ShowDialog(Dictionary parameters) where T : DialogViewModelBase { - var viewModel = parameters != null ? _kernel.Get(parameters) : _kernel.Get(); - return await ShowDialog(identifier, viewModel); + if (parameters == null) + throw new ArgumentNullException(nameof(parameters)); + + var paramsArray = parameters.Select(kv => new ConstructorArgument(kv.Key, kv.Value)).Cast().ToArray(); + return ShowDialog(paramsArray); + } + + public async Task ShowDialog(IParameter[] parameters) where T : DialogViewModelBase + { + if (parameters == null) throw new ArgumentNullException(nameof(parameters)); + return await ShowDialog("RootDialog", _kernel.Get(parameters)); + } + + public async Task ShowDialogAt(string identifier) where T : DialogViewModelBase + { + return await ShowDialog(identifier, _kernel.Get()); + } + + public async Task ShowDialogAt(string identifier, Dictionary parameters) where T : DialogViewModelBase + { + if (parameters == null) + throw new ArgumentNullException(nameof(parameters)); + + var paramsArray = parameters.Select(kv => new ConstructorArgument(kv.Key, kv.Value)).Cast().ToArray(); + return await ShowDialogAt(identifier, paramsArray); + } + + public async Task ShowDialogAt(string identifier, IParameter[] parameters) where T : DialogViewModelBase + { + if (parameters == null) throw new ArgumentNullException(nameof(parameters)); + return await ShowDialog(identifier, _kernel.Get(parameters)); } private async Task ShowDialog(string identifier, DialogViewModelBase viewModel) diff --git a/src/Artemis.UI/Services/Interfaces/IDialogService.cs b/src/Artemis.UI/Services/Interfaces/IDialogService.cs index d8591ce36..10486929b 100644 --- a/src/Artemis.UI/Services/Interfaces/IDialogService.cs +++ b/src/Artemis.UI/Services/Interfaces/IDialogService.cs @@ -1,14 +1,97 @@ -using System.Threading.Tasks; +using System.Collections.Generic; +using System.Threading.Tasks; using Artemis.UI.ViewModels.Dialogs; +using MaterialDesignThemes.Wpf; using Ninject.Parameters; namespace Artemis.UI.Services.Interfaces { public interface IDialogService : IArtemisUIService { + /// + /// Shows a confirm dialog on the dialog host provided in . + /// + /// The title of the dialog + /// The body text of the dialog + /// The text of the confirm button, defaults to "Confirm" + /// The text of the cancel button, defaults to "Cancel" + /// A task that resolves to true if confirmed and false if cancelled Task ShowConfirmDialog(string header, string text, string confirmText = "Confirm", string cancelText = "Cancel"); + + /// + /// Shows a confirm dialog on the dialog host provided in . + /// + /// + /// The identifier of the to use eg. + /// <materialDesign:DialogHost Identifier="MyDialogHost"> + /// + /// The title of the dialog + /// The body text of the dialog + /// The text of the confirm button, defaults to "Confirm" + /// The text of the cancel button, defaults to "Cancel" + /// A task that resolves to true if confirmed and false if cancelled Task ShowConfirmDialogAt(string identifier, string header, string text, string confirmText = "Confirm", string cancelText = "Cancel"); - Task ShowDialog(IParameter[] parameters = null) where T : DialogViewModelBase; - Task ShowDialogAt(string identifier, IParameter[] parameters = null) where T : DialogViewModelBase; + + /// + /// Shows a dialog by initializing a view model implementing + /// + /// The type of the view model + /// A task resolving to the result of the dialog's + Task ShowDialog() where T : DialogViewModelBase; + + /// + /// Shows a dialog by initializing a view model implementing with arguments passed + /// to the view models constructor + /// + /// The type of the view model + /// A dictionary of constructor arguments to pass to the view model + /// A task resolving to the result of the dialog's + Task ShowDialog(Dictionary parameters) where T : DialogViewModelBase; + + /// + /// Shows a dialog by initializing a view model implementing using an array of + /// Ninject , requires you to reference Ninject + /// + /// The type of the view model + /// An array of Ninject to pass to the view model during activation + /// A task resolving to the result of the dialog's + Task ShowDialog(IParameter[] parameters) where T : DialogViewModelBase; + + /// + /// Shows a dialog by initializing a view model implementing + /// + /// The type of the view model + /// + /// The identifier of the to use eg. + /// <materialDesign:DialogHost Identifier="MyDialogHost"> + /// + /// A task resolving to the result of the dialog's + Task ShowDialogAt(string identifier) where T : DialogViewModelBase; + + /// + /// Shows a dialog by initializing a view model implementing with arguments passed + /// to the view models constructor + /// + /// The type of the view model + /// + /// The identifier of the to use eg. + /// <materialDesign:DialogHost Identifier="MyDialogHost"> + /// + /// A dictionary of constructor arguments to pass to the view model + /// A task resolving to the result of the dialog's + Task ShowDialogAt(string identifier, Dictionary parameters) where T : DialogViewModelBase; + + /// + /// Shows a dialog by initializing a view model implementing using an array of + /// Ninject , requires you to reference Ninject + /// + /// The type of the view model + /// + /// The identifier of the to use eg. + /// <materialDesign:DialogHost Identifier="MyDialogHost"> + /// + /// An array of Ninject to pass to the view model during activation + /// A task resolving to the result of the dialog's + Task ShowDialogAt(string identifier, IParameter[] parameters) where T : DialogViewModelBase; } } \ No newline at end of file