1
0
mirror of https://github.com/Artemis-RGB/Artemis synced 2026-01-02 10:43:31 +00:00

Device properties - UI polish (the shiny kind)

Conditions - Open existing condition path on click
This commit is contained in:
Robert 2021-03-11 00:44:46 +01:00
parent d5d1211649
commit 98b9770250
9 changed files with 263 additions and 135 deletions

View File

@ -239,6 +239,7 @@ namespace Artemis.Core.Services
public void ApplyDeviceLayout(ArtemisDevice device, ArtemisLayout layout, bool createMissingLeds, bool removeExessiveLeds) public void ApplyDeviceLayout(ArtemisDevice device, ArtemisLayout layout, bool createMissingLeds, bool removeExessiveLeds)
{ {
device.ApplyLayout(layout, createMissingLeds, removeExessiveLeds); device.ApplyLayout(layout, createMissingLeds, removeExessiveLeds);
UpdateLedGroup();
} }
public ArtemisDevice? GetDevice(IRGBDevice rgbDevice) public ArtemisDevice? GetDevice(IRGBDevice rgbDevice)

View File

@ -51,7 +51,7 @@ namespace Artemis.UI.Shared
byte g = Led.RgbLed.Color.GetG(); byte g = Led.RgbLed.Color.GetG();
byte b = Led.RgbLed.Color.GetB(); byte b = Led.RgbLed.Color.GetB();
_renderColor.A = (byte)(isDimmed ? 100 : 255); _renderColor.A = (byte) (isDimmed ? 100 : 255);
_renderColor.A = isDimmed ? Dimmed : NonDimmed; _renderColor.A = isDimmed ? Dimmed : NonDimmed;
_renderColor.R = r; _renderColor.R = r;
_renderColor.G = g; _renderColor.G = g;
@ -135,6 +135,8 @@ namespace Artemis.UI.Shared
{ {
try try
{ {
double width = Led.RgbLed.Size.Width - deflateAmount;
double height = Led.RgbLed.Size.Height - deflateAmount;
// DisplayGeometry = Geometry.Parse(Led.RgbLed.ShapeData); // DisplayGeometry = Geometry.Parse(Led.RgbLed.ShapeData);
DisplayGeometry = Geometry.Combine( DisplayGeometry = Geometry.Combine(
Geometry.Empty, Geometry.Empty,
@ -144,11 +146,27 @@ namespace Artemis.UI.Shared
{ {
Children = new TransformCollection Children = new TransformCollection
{ {
new ScaleTransform(Led.RgbLed.Size.Width - deflateAmount, Led.RgbLed.Size.Height - deflateAmount), new ScaleTransform(width, height),
new TranslateTransform(deflateAmount / 2, deflateAmount / 2) new TranslateTransform(deflateAmount / 2, deflateAmount / 2)
} }
} }
); );
if (DisplayGeometry.Bounds.Width > width)
{
DisplayGeometry = Geometry.Combine(Geometry.Empty, DisplayGeometry, GeometryCombineMode.Union, new TransformGroup
{
Children = new TransformCollection {new ScaleTransform(width / DisplayGeometry.Bounds.Width, 1)}
});
}
if (DisplayGeometry.Bounds.Height > height)
{
DisplayGeometry = Geometry.Combine(Geometry.Empty, DisplayGeometry, GeometryCombineMode.Union, new TransformGroup
{
Children = new TransformCollection {new ScaleTransform(1, height / DisplayGeometry.Bounds.Height)}
});
}
} }
catch (Exception) catch (Exception)
{ {

View File

@ -1,4 +1,5 @@
using System; using System;
using System.Collections.Generic;
using System.Collections.Specialized; using System.Collections.Specialized;
using System.Linq; using System.Linq;
using System.Timers; using System.Timers;
@ -139,7 +140,11 @@ namespace Artemis.UI.Shared.Input
set set
{ {
if (!SetAndNotify(ref _isDataModelViewModelOpen, value)) return; if (!SetAndNotify(ref _isDataModelViewModelOpen, value)) return;
if (value) UpdateDataModelVisualization(); if (value)
{
UpdateDataModelVisualization();
OpenSelectedValue(DataModelViewModel);
}
} }
} }
@ -303,6 +308,21 @@ namespace Artemis.UI.Shared.Input
extraDataModelViewModel.Update(_dataModelUIService, new DataModelUpdateConfiguration(LoadEventChildren)); extraDataModelViewModel.Update(_dataModelUIService, new DataModelUpdateConfiguration(LoadEventChildren));
} }
private void OpenSelectedValue(DataModelVisualizationViewModel dataModelPropertiesViewModel)
{
if (DataModelPath == null)
return;
if (dataModelPropertiesViewModel.Children.Any(c => c.DataModelPath != null && DataModelPath.Path.StartsWith(c.DataModelPath.Path)))
{
dataModelPropertiesViewModel.IsVisualizationExpanded = true;
foreach (DataModelVisualizationViewModel dataModelVisualizationViewModel in dataModelPropertiesViewModel.Children)
{
OpenSelectedValue(dataModelVisualizationViewModel);
}
}
}
#endregion #endregion
#region Events #region Events

View File

@ -24,6 +24,12 @@
<mde:MaterialWindow.InputBindings> <mde:MaterialWindow.InputBindings>
<KeyBinding Command="{s:Action ClearSelection}" Key="Escape" /> <KeyBinding Command="{s:Action ClearSelection}" Key="Escape" />
</mde:MaterialWindow.InputBindings> </mde:MaterialWindow.InputBindings>
<materialDesign:DialogHost IsTabStop="False"
Focusable="False"
Identifier="DeviceDialog"
DialogTheme="Inherit"
SnackbarMessageQueue="{Binding DeviceMessageQueue}">
<DockPanel> <DockPanel>
<mde:AppBar Type="Dense" <mde:AppBar Type="Dense"
Title="{Binding Device.RgbDevice.DeviceInfo.Model}" Title="{Binding Device.RgbDevice.DeviceInfo.Model}"
@ -112,6 +118,7 @@
<materialDesign:Card Grid.Column="2" <materialDesign:Card Grid.Column="2"
materialDesign:ShadowAssist.ShadowDepth="Depth3" materialDesign:ShadowAssist.ShadowDepth="Depth3"
Background="{DynamicResource MaterialDesignPaper}"> Background="{DynamicResource MaterialDesignPaper}">
<Grid>
<TabControl <TabControl
Style="{StaticResource MaterialDesignTabControl}" Style="{StaticResource MaterialDesignTabControl}"
ItemsSource="{Binding Items}" ItemsSource="{Binding Items}"
@ -127,7 +134,14 @@
</DataTemplate> </DataTemplate>
</TabControl.ContentTemplate> </TabControl.ContentTemplate>
</TabControl> </TabControl>
<materialDesign:Snackbar x:Name="DeviceSnackbar"
MessageQueue="{Binding DeviceMessageQueue}"
materialDesign:SnackbarMessage.InlineActionButtonMaxHeight="80"
materialDesign:SnackbarMessage.ContentMaxHeight="200" />
</Grid>
</materialDesign:Card> </materialDesign:Card>
</Grid> </Grid>
</DockPanel> </DockPanel>
</materialDesign:DialogHost>
</mde:MaterialWindow> </mde:MaterialWindow>

View File

@ -9,6 +9,7 @@ using Artemis.Core.Services;
using Artemis.UI.Ninject.Factories; using Artemis.UI.Ninject.Factories;
using Artemis.UI.Screens.Shared; using Artemis.UI.Screens.Shared;
using Artemis.UI.Shared.Services; using Artemis.UI.Shared.Services;
using MaterialDesignThemes.Wpf;
using Ookii.Dialogs.Wpf; using Ookii.Dialogs.Wpf;
using RGB.NET.Layout; using RGB.NET.Layout;
using Stylet; using Stylet;
@ -21,6 +22,7 @@ namespace Artemis.UI.Screens.Settings.Device
private readonly IDialogService _dialogService; private readonly IDialogService _dialogService;
private readonly IRgbService _rgbService; private readonly IRgbService _rgbService;
private ArtemisLed _selectedLed; private ArtemisLed _selectedLed;
private SnackbarMessageQueue _deviceMessageQueue;
public DeviceDialogViewModel(ArtemisDevice device, IDeviceService deviceService, IRgbService rgbService, IDialogService dialogService, IDeviceDebugVmFactory factory) public DeviceDialogViewModel(ArtemisDevice device, IDeviceService deviceService, IRgbService rgbService, IDialogService dialogService, IDeviceDebugVmFactory factory)
{ {
@ -38,9 +40,28 @@ namespace Artemis.UI.Screens.Settings.Device
DisplayName = $"{device.RgbDevice.DeviceInfo.Model} | Artemis"; DisplayName = $"{device.RgbDevice.DeviceInfo.Model} | Artemis";
} }
protected override void OnInitialActivate()
{
DeviceMessageQueue = new SnackbarMessageQueue(TimeSpan.FromSeconds(5));
Device.DeviceUpdated += DeviceOnDeviceUpdated;
base.OnInitialActivate();
}
protected override void OnClose()
{
Device.DeviceUpdated -= DeviceOnDeviceUpdated;
base.OnClose();
}
public ArtemisDevice Device { get; } public ArtemisDevice Device { get; }
public PanZoomViewModel PanZoomViewModel { get; } public PanZoomViewModel PanZoomViewModel { get; }
public SnackbarMessageQueue DeviceMessageQueue
{
get => _deviceMessageQueue;
set => SetAndNotify(ref _deviceMessageQueue, value);
}
public ArtemisLed SelectedLed public ArtemisLed SelectedLed
{ {
get => _selectedLed; get => _selectedLed;
@ -50,7 +71,10 @@ namespace Artemis.UI.Screens.Settings.Device
NotifyOfPropertyChange(nameof(SelectedLeds)); NotifyOfPropertyChange(nameof(SelectedLeds));
} }
} }
public List<ArtemisLed> SelectedLeds => SelectedLed != null ? new List<ArtemisLed> { SelectedLed } : null;
public bool CanExportLayout => Device.Layout?.IsValid ?? false;
public List<ArtemisLed> SelectedLeds => SelectedLed != null ? new List<ArtemisLed> {SelectedLed} : null;
public bool CanOpenImageDirectory => Device.Layout?.Image != null; public bool CanOpenImageDirectory => Device.Layout?.Image != null;
@ -165,5 +189,14 @@ namespace Artemis.UI.Screens.Settings.Device
#endregion #endregion
// ReSharper restore UnusedMember.Global // ReSharper restore UnusedMember.Global
#region Event handlers
private void DeviceOnDeviceUpdated(object? sender, EventArgs e)
{
NotifyOfPropertyChange(nameof(CanExportLayout));
}
#endregion
} }
} }

View File

@ -91,15 +91,21 @@
<ColumnDefinition Width="*" /> <ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" /> <ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<TextBlock Style="{StaticResource MaterialDesignTextBlock}">Layout file path</TextBlock> <TextBlock Style="{StaticResource MaterialDesignTextBlock}">Default layout file path</TextBlock>
<Button Grid.Column="1" Style="{StaticResource MaterialDesignIconForegroundButton}" ToolTip="Copy path to clipboard" Width="24" Height="24"> <Button Grid.Column="1"
Style="{StaticResource MaterialDesignIconForegroundButton}"
ToolTip="Copy path to clipboard"
Width="24"
Height="24"
Command="{s:Action CopyToClipboard}"
CommandParameter="{Binding DefaultLayoutPath}">
<materialDesign:PackIcon Kind="ContentCopy" Width="18" Height="18" /> <materialDesign:PackIcon Kind="ContentCopy" Width="18" Height="18" />
</Button> </Button>
</Grid> </Grid>
<TextBlock Style="{StaticResource MaterialDesignTextBlock}" <TextBlock Style="{StaticResource MaterialDesignTextBlock}"
Foreground="{DynamicResource MaterialDesignNavigationItemSubheader}" Foreground="{DynamicResource MaterialDesignNavigationItemSubheader}"
TextWrapping="Wrap" TextWrapping="Wrap"
Text="{Binding Device.Layout.FilePath}" /> Text="{Binding DefaultLayoutPath}" />
<Separator Style="{StaticResource MaterialDesignSeparator}" Margin="0 5" /> <Separator Style="{StaticResource MaterialDesignSeparator}" Margin="0 5" />
<Grid> <Grid>
@ -108,14 +114,19 @@
<ColumnDefinition Width="Auto" /> <ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<TextBlock Style="{StaticResource MaterialDesignTextBlock}">Image file path</TextBlock> <TextBlock Style="{StaticResource MaterialDesignTextBlock}">Image file path</TextBlock>
<Button Grid.Column="1" Style="{StaticResource MaterialDesignIconForegroundButton}" ToolTip="Copy path to clipboard" Width="24" Height="24"> <Button Grid.Column="1" Style="{StaticResource MaterialDesignIconForegroundButton}"
ToolTip="Copy path to clipboard"
Width="24"
Height="24"
Command="{s:Action CopyToClipboard}"
CommandParameter="{Binding Device.Layout.Image.LocalPath}">
<materialDesign:PackIcon Kind="ContentCopy" Width="18" Height="18" /> <materialDesign:PackIcon Kind="ContentCopy" Width="18" Height="18" />
</Button> </Button>
</Grid> </Grid>
<TextBlock Style="{StaticResource MaterialDesignTextBlock}" <TextBlock Style="{StaticResource MaterialDesignTextBlock}"
Foreground="{DynamicResource MaterialDesignNavigationItemSubheader}" Foreground="{DynamicResource MaterialDesignNavigationItemSubheader}"
TextWrapping="Wrap" TextWrapping="Wrap"
Text="{Binding Device.Layout.Image}" /> Text="{Binding Device.Layout.Image.LocalPath}" />
</StackPanel> </StackPanel>
</Grid> </Grid>
</UserControl> </UserControl>

View File

@ -1,4 +1,5 @@
using Artemis.Core; using System.Windows;
using Artemis.Core;
using RGB.NET.Core; using RGB.NET.Core;
using Stylet; using Stylet;
@ -6,6 +7,8 @@ namespace Artemis.UI.Screens.Settings.Device.Tabs
{ {
public class DeviceInfoTabViewModel : Screen public class DeviceInfoTabViewModel : Screen
{ {
private string _defaultLayoutPath;
public DeviceInfoTabViewModel(ArtemisDevice device) public DeviceInfoTabViewModel(ArtemisDevice device)
{ {
Device = device; Device = device;
@ -14,5 +17,23 @@ namespace Artemis.UI.Screens.Settings.Device.Tabs
public bool IsKeyboard => Device.RgbDevice.DeviceInfo.DeviceType == RGBDeviceType.Keyboard; public bool IsKeyboard => Device.RgbDevice.DeviceInfo.DeviceType == RGBDeviceType.Keyboard;
public ArtemisDevice Device { get; } public ArtemisDevice Device { get; }
public string DefaultLayoutPath
{
get => _defaultLayoutPath;
set => SetAndNotify(ref _defaultLayoutPath, value);
}
public void CopyToClipboard(string content)
{
Clipboard.SetText(content);
((DeviceDialogViewModel) Parent).DeviceMessageQueue.Enqueue("Copied path to clipboard.");
}
protected override void OnInitialActivate()
{
DefaultLayoutPath = Device.DeviceProvider.LoadLayout(Device).FilePath;
base.OnInitialActivate();
}
} }
} }

View File

@ -174,14 +174,23 @@
</StackPanel> </StackPanel>
</materialDesign:HintAssist.Hint> </materialDesign:HintAssist.Hint>
</TextBox> </TextBox>
<Button Style="{StaticResource MaterialDesignRaisedButton}" Margin="0 8 8 0" Command="{s:Action SelectPhysicalLayout}">
SELECT PHYSICAL LAYOUT (PLACEHOLDER)
</Button>
</StackPanel> </StackPanel>
<!-- Buttons --> <!-- Buttons -->
<StackPanel Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Right"> <Grid Grid.Row="1" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Button Grid.Column="0"
Style="{StaticResource MaterialDesignOutlinedButton}"
Margin="0 8 8 0"
Command="{s:Action SelectPhysicalLayout}"
ToolTip="Restart device setup, allowing you to select a new physical and logical layout">
RESTART SETUP
</Button>
<StackPanel Grid.Column="1" Orientation="Horizontal" HorizontalAlignment="Right">
<Button Style="{StaticResource MaterialDesignOutlinedButton}" IsCancel="True" Margin="0 8 8 0" Command="{s:Action Reset}"> <Button Style="{StaticResource MaterialDesignOutlinedButton}" IsCancel="True" Margin="0 8 8 0" Command="{s:Action Reset}">
RESET RESET
</Button> </Button>
@ -190,4 +199,6 @@
</Button> </Button>
</StackPanel> </StackPanel>
</Grid> </Grid>
</Grid>
</UserControl> </UserControl>

View File

@ -15,7 +15,6 @@ namespace Artemis.UI.Screens.Settings.Device.Tabs
public class DevicePropertiesTabViewModel : Screen public class DevicePropertiesTabViewModel : Screen
{ {
private readonly ICoreService _coreService; private readonly ICoreService _coreService;
private readonly IMessageService _messageService;
private readonly IDialogService _dialogService; private readonly IDialogService _dialogService;
private readonly IRgbService _rgbService; private readonly IRgbService _rgbService;
private float _blueScale; private float _blueScale;
@ -34,13 +33,11 @@ namespace Artemis.UI.Screens.Settings.Device.Tabs
public DevicePropertiesTabViewModel(ArtemisDevice device, public DevicePropertiesTabViewModel(ArtemisDevice device,
ICoreService coreService, ICoreService coreService,
IRgbService rgbService, IRgbService rgbService,
IMessageService messageService,
IDialogService dialogService, IDialogService dialogService,
IModelValidator<DevicePropertiesTabViewModel> validator) : base(validator) IModelValidator<DevicePropertiesTabViewModel> validator) : base(validator)
{ {
_coreService = coreService; _coreService = coreService;
_rgbService = rgbService; _rgbService = rgbService;
_messageService = messageService;
_dialogService = dialogService; _dialogService = dialogService;
Device = device; Device = device;
@ -115,7 +112,7 @@ namespace Artemis.UI.Screens.Settings.Device.Tabs
if (e.OriginalSource is Button) if (e.OriginalSource is Button)
{ {
Device.CustomLayoutPath = null; Device.CustomLayoutPath = null;
_messageService.ShowMessage("Cleared imported layout"); ((DeviceDialogViewModel) Parent).DeviceMessageQueue.Enqueue("Cleared imported layout.");
return; return;
} }
@ -126,13 +123,13 @@ namespace Artemis.UI.Screens.Settings.Device.Tabs
if (result == true) if (result == true)
{ {
Device.CustomLayoutPath = dialog.FileName; Device.CustomLayoutPath = dialog.FileName;
_messageService.ShowMessage($"Imported layout from {dialog.FileName}"); ((DeviceDialogViewModel) Parent).DeviceMessageQueue.Enqueue($"Imported layout from {dialog.FileName}.");
} }
} }
public async Task SelectPhysicalLayout() public async Task SelectPhysicalLayout()
{ {
await _dialogService.ShowDialog<DeviceLayoutDialogViewModel>(new Dictionary<string, object> {{"device", Device}}); await _dialogService.ShowDialogAt<DeviceLayoutDialogViewModel>("DeviceDialog", new Dictionary<string, object> {{"device", Device}});
} }
public async Task Apply() public async Task Apply()
@ -151,6 +148,7 @@ namespace Artemis.UI.Screens.Settings.Device.Tabs
Device.RedScale = RedScale / 100f; Device.RedScale = RedScale / 100f;
Device.GreenScale = GreenScale / 100f; Device.GreenScale = GreenScale / 100f;
Device.BlueScale = BlueScale / 100f; Device.BlueScale = BlueScale / 100f;
_rgbService.SaveDevice(Device);
_coreService.ModuleRenderingDisabled = false; _coreService.ModuleRenderingDisabled = false;
} }
@ -195,7 +193,8 @@ namespace Artemis.UI.Screens.Settings.Device.Tabs
private void DeviceOnPropertyChanged(object sender, PropertyChangedEventArgs e) private void DeviceOnPropertyChanged(object sender, PropertyChangedEventArgs e)
{ {
if (e.PropertyName == nameof(Device.CustomLayoutPath)) _rgbService.ApplyBestDeviceLayout(Device); if (e.PropertyName == nameof(Device.CustomLayoutPath))
_rgbService.ApplyBestDeviceLayout(Device);
} }
private void OnFrameRendering(object sender, FrameRenderingEventArgs e) private void OnFrameRendering(object sender, FrameRenderingEventArgs e)