mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-13 05:48:35 +00:00
Sidebar - Put all options under the cogwheel button and right-mouse-menu
Sidebar - Hide the cogwheel button when not hoving over category/profile Sidebar - Made it easier to drag profiles into an empty category
This commit is contained in:
parent
65a2aa70e2
commit
6ed349d4c8
@ -2,12 +2,14 @@
|
|||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:sidebar="clr-namespace:Artemis.UI.Screens.Sidebar"
|
||||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||||
x:Class="Artemis.UI.Screens.Sidebar.SidebarCategoryEditView">
|
x:Class="Artemis.UI.Screens.Sidebar.SidebarCategoryEditView"
|
||||||
|
x:DataType="sidebar:SidebarCategoryEditViewModel">
|
||||||
<StackPanel>
|
<StackPanel>
|
||||||
<StackPanel.KeyBindings>
|
<StackPanel.KeyBindings>
|
||||||
<KeyBinding Gesture="Enter" Command="{Binding Confirm}" />
|
<KeyBinding Gesture="Enter" Command="{CompiledBinding Confirm}" />
|
||||||
</StackPanel.KeyBindings>
|
</StackPanel.KeyBindings>
|
||||||
<TextBox Text="{Binding CategoryName}" Watermark="Category name"/>
|
<TextBox Text="{CompiledBinding CategoryName}" Watermark="Category name"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</UserControl>
|
</UserControl>
|
||||||
@ -23,13 +23,9 @@ public class SidebarCategoryEditViewModel : ContentDialogViewModelBase
|
|||||||
_categoryName = _category.Name;
|
_categoryName = _category.Name;
|
||||||
|
|
||||||
Confirm = ReactiveCommand.Create(ExecuteConfirm, ValidationContext.Valid);
|
Confirm = ReactiveCommand.Create(ExecuteConfirm, ValidationContext.Valid);
|
||||||
Delete = ReactiveCommand.Create(ExecuteDelete);
|
|
||||||
|
|
||||||
this.ValidationRule(vm => vm.CategoryName, categoryName => !string.IsNullOrWhiteSpace(categoryName), "You must specify a valid name");
|
this.ValidationRule(vm => vm.CategoryName, categoryName => !string.IsNullOrWhiteSpace(categoryName), "You must specify a valid name");
|
||||||
}
|
}
|
||||||
|
|
||||||
public ReactiveCommand<Unit, Unit> Delete { get; set; }
|
|
||||||
|
|
||||||
public string? CategoryName
|
public string? CategoryName
|
||||||
{
|
{
|
||||||
get => _categoryName;
|
get => _categoryName;
|
||||||
@ -52,10 +48,4 @@ public class SidebarCategoryEditViewModel : ContentDialogViewModelBase
|
|||||||
|
|
||||||
ContentDialog?.Hide(ContentDialogResult.Primary);
|
ContentDialog?.Hide(ContentDialogResult.Primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ExecuteDelete()
|
|
||||||
{
|
|
||||||
if (_category != null)
|
|
||||||
_profileService.DeleteProfileCategory(_category);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@ -76,18 +76,20 @@
|
|||||||
|
|
||||||
<StackPanel Orientation="Horizontal"
|
<StackPanel Orientation="Horizontal"
|
||||||
IsVisible="{CompiledBinding IconType, Converter={StaticResource EnumBoolConverter}, ConverterParameter={x:Static core:ProfileConfigurationIconType.BitmapImage}}">
|
IsVisible="{CompiledBinding IconType, Converter={StaticResource EnumBoolConverter}, ConverterParameter={x:Static core:ProfileConfigurationIconType.BitmapImage}}">
|
||||||
|
|
||||||
<Border IsVisible="{CompiledBinding ProfileConfiguration.Icon.Fill}" Background="{DynamicResource CheckerboardBrush}" CornerRadius="{DynamicResource CardCornerRadius}" Width="78" Height="78">
|
<Border IsVisible="{CompiledBinding ProfileConfiguration.Icon.Fill}" Background="{DynamicResource CheckerboardBrush}" CornerRadius="{DynamicResource CardCornerRadius}"
|
||||||
|
Width="78" Height="78">
|
||||||
<Border Name="FillPreview" Background="{DynamicResource TextFillColorPrimary}" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Margin="10">
|
<Border Name="FillPreview" Background="{DynamicResource TextFillColorPrimary}" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Margin="10">
|
||||||
<Border.OpacityMask>
|
<Border.OpacityMask>
|
||||||
<ImageBrush Source="{CompiledBinding SelectedBitmapSource}" BitmapInterpolationMode="HighQuality" />
|
<ImageBrush Source="{CompiledBinding SelectedBitmapSource}" BitmapInterpolationMode="HighQuality" />
|
||||||
</Border.OpacityMask>
|
</Border.OpacityMask>
|
||||||
</Border>
|
</Border>
|
||||||
</Border>
|
</Border>
|
||||||
<Border IsVisible="{CompiledBinding !ProfileConfiguration.Icon.Fill}" Background="{DynamicResource CheckerboardBrush}" CornerRadius="{DynamicResource CardCornerRadius}" Width="78" Height="78">
|
<Border IsVisible="{CompiledBinding !ProfileConfiguration.Icon.Fill}" Background="{DynamicResource CheckerboardBrush}" CornerRadius="{DynamicResource CardCornerRadius}"
|
||||||
|
Width="78" Height="78">
|
||||||
<Image Source="{CompiledBinding SelectedBitmapSource}" Margin="10" />
|
<Image Source="{CompiledBinding SelectedBitmapSource}" Margin="10" />
|
||||||
</Border>
|
</Border>
|
||||||
|
|
||||||
<Button Command="{CompiledBinding BrowseBitmapFile}"
|
<Button Command="{CompiledBinding BrowseBitmapFile}"
|
||||||
VerticalAlignment="Bottom"
|
VerticalAlignment="Bottom"
|
||||||
Margin="10 0"
|
Margin="10 0"
|
||||||
@ -96,7 +98,7 @@
|
|||||||
</Button>
|
</Button>
|
||||||
<CheckBox VerticalAlignment="Bottom" IsChecked="{CompiledBinding ProfileConfiguration.Icon.Fill}">Fill</CheckBox>
|
<CheckBox VerticalAlignment="Bottom" IsChecked="{CompiledBinding ProfileConfiguration.Icon.Fill}">Fill</CheckBox>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
<StackPanel Orientation="Horizontal"
|
<StackPanel Orientation="Horizontal"
|
||||||
IsVisible="{CompiledBinding IconType, Converter={StaticResource EnumBoolConverter}, ConverterParameter={x:Static core:ProfileConfigurationIconType.MaterialIcon}}">
|
IsVisible="{CompiledBinding IconType, Converter={StaticResource EnumBoolConverter}, ConverterParameter={x:Static core:ProfileConfigurationIconType.MaterialIcon}}">
|
||||||
<Border Background="{DynamicResource CheckerboardBrush}" CornerRadius="{DynamicResource CardCornerRadius}" Width="78" Height="78">
|
<Border Background="{DynamicResource CheckerboardBrush}" CornerRadius="{DynamicResource CardCornerRadius}" Width="78" Height="78">
|
||||||
@ -169,8 +171,8 @@
|
|||||||
<Border CornerRadius="5" ClipToBounds="True">
|
<Border CornerRadius="5" ClipToBounds="True">
|
||||||
<ContentControl Content="{CompiledBinding VisualEditorViewModel}" Height="150" />
|
<ContentControl Content="{CompiledBinding VisualEditorViewModel}" Height="150" />
|
||||||
</Border>
|
</Border>
|
||||||
<Border Background="Black" Opacity="0.5" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" CornerRadius="5"/>
|
<Border Background="Black" Opacity="0.5" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" CornerRadius="5" />
|
||||||
|
|
||||||
<Button DockPanel.Dock="Bottom"
|
<Button DockPanel.Dock="Bottom"
|
||||||
ToolTip.Tip="Open editor"
|
ToolTip.Tip="Open editor"
|
||||||
HorizontalAlignment="Center"
|
HorizontalAlignment="Center"
|
||||||
@ -185,12 +187,11 @@
|
|||||||
</StackPanel>
|
</StackPanel>
|
||||||
</ScrollViewer>
|
</ScrollViewer>
|
||||||
|
|
||||||
<Grid Grid.Row="1" ColumnDefinitions="Auto,Auto,Auto" HorizontalAlignment="Right">
|
<StackPanel Grid.Row="1" Spacing="5" HorizontalAlignment="Right" Orientation="Horizontal">
|
||||||
<Button Grid.Column="0" Classes="accent" Command="{CompiledBinding Confirm}">Confirm</Button>
|
<Button Command="{CompiledBinding Confirm}" Classes="accent">Confirm</Button>
|
||||||
<Button Grid.Column="1" Margin="5" Command="{CompiledBinding Import}" IsVisible="{CompiledBinding IsNew}">Import</Button>
|
<Button Command="{CompiledBinding Delete}" IsVisible="{CompiledBinding !IsNew}">Delete</Button>
|
||||||
<Button Grid.Column="1" Margin="5" Command="{CompiledBinding Delete}" IsVisible="{CompiledBinding !IsNew}">Delete</Button>
|
<Button Command="{CompiledBinding Cancel}">Cancel</Button>
|
||||||
<Button Grid.Column="2" Command="{CompiledBinding Cancel}">Cancel</Button>
|
</StackPanel>
|
||||||
</Grid>
|
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
</controls1:CoreWindow>
|
</controls1:CoreWindow>
|
||||||
@ -63,7 +63,7 @@ public class ProfileConfigurationEditViewModel : DialogViewModelBase<ProfileConf
|
|||||||
_disableHotkey = new Hotkey {Key = _profileConfiguration.DisableHotkey.Key, Modifiers = _profileConfiguration.DisableHotkey.Modifiers};
|
_disableHotkey = new Hotkey {Key = _profileConfiguration.DisableHotkey.Key, Modifiers = _profileConfiguration.DisableHotkey.Modifiers};
|
||||||
|
|
||||||
IsNew = profileConfiguration == null;
|
IsNew = profileConfiguration == null;
|
||||||
DisplayName = IsNew ? "Artemis | Add profile" : "Artemis | Edit profile";
|
DisplayName = IsNew ? "Artemis | Add profile" : "Artemis | Edit profile properties";
|
||||||
Modules = new ObservableCollection<ProfileModuleViewModel?>(
|
Modules = new ObservableCollection<ProfileModuleViewModel?>(
|
||||||
pluginManagementService.GetFeaturesOfType<Module>().Where(m => !m.IsAlwaysAvailable).Select(m => new ProfileModuleViewModel(m))
|
pluginManagementService.GetFeaturesOfType<Module>().Where(m => !m.IsAlwaysAvailable).Select(m => new ProfileModuleViewModel(m))
|
||||||
);
|
);
|
||||||
@ -75,7 +75,6 @@ public class ProfileConfigurationEditViewModel : DialogViewModelBase<ProfileConf
|
|||||||
BrowseBitmapFile = ReactiveCommand.CreateFromTask(ExecuteBrowseBitmapFile);
|
BrowseBitmapFile = ReactiveCommand.CreateFromTask(ExecuteBrowseBitmapFile);
|
||||||
OpenConditionEditor = ReactiveCommand.CreateFromTask(ExecuteOpenConditionEditor);
|
OpenConditionEditor = ReactiveCommand.CreateFromTask(ExecuteOpenConditionEditor);
|
||||||
Confirm = ReactiveCommand.CreateFromTask(ExecuteConfirm);
|
Confirm = ReactiveCommand.CreateFromTask(ExecuteConfirm);
|
||||||
Import = ReactiveCommand.CreateFromTask(ExecuteImport);
|
|
||||||
Delete = ReactiveCommand.CreateFromTask(ExecuteDelete);
|
Delete = ReactiveCommand.CreateFromTask(ExecuteDelete);
|
||||||
Cancel = ReactiveCommand.Create(ExecuteCancel);
|
Cancel = ReactiveCommand.Create(ExecuteCancel);
|
||||||
|
|
||||||
@ -135,51 +134,7 @@ public class ProfileConfigurationEditViewModel : DialogViewModelBase<ProfileConf
|
|||||||
public ReactiveCommand<Unit, Unit> Import { get; }
|
public ReactiveCommand<Unit, Unit> Import { get; }
|
||||||
public ReactiveCommand<Unit, Unit> Delete { get; }
|
public ReactiveCommand<Unit, Unit> Delete { get; }
|
||||||
public ReactiveCommand<Unit, Unit> Cancel { get; }
|
public ReactiveCommand<Unit, Unit> Cancel { get; }
|
||||||
|
|
||||||
private async Task ExecuteImport()
|
|
||||||
{
|
|
||||||
if (!IsNew)
|
|
||||||
return;
|
|
||||||
|
|
||||||
string[]? result = await _windowService.CreateOpenFileDialog()
|
|
||||||
.HavingFilter(f => f.WithExtension("json").WithName("Artemis profile"))
|
|
||||||
.ShowAsync();
|
|
||||||
|
|
||||||
if (result == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
string json = await File.ReadAllTextAsync(result[0]);
|
|
||||||
ProfileConfigurationExportModel? profileConfigurationExportModel = null;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
profileConfigurationExportModel = JsonConvert.DeserializeObject<ProfileConfigurationExportModel>(json, IProfileService.ExportSettings);
|
|
||||||
}
|
|
||||||
catch (JsonException e)
|
|
||||||
{
|
|
||||||
_windowService.ShowExceptionDialog("Import profile failed", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (profileConfigurationExportModel == null)
|
|
||||||
{
|
|
||||||
await _windowService.ShowConfirmContentDialog("Import profile", "Failed to import this profile, make sure it is a valid Artemis profile.", "Confirm", null);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
ProfileConfiguration profileConfiguration = _profileService.ImportProfile(_profileCategory, profileConfigurationExportModel);
|
|
||||||
|
|
||||||
// Remove the temporary profile configuration
|
|
||||||
_profileService.RemoveProfileConfiguration(_profileConfiguration);
|
|
||||||
|
|
||||||
Close(profileConfiguration);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
_windowService.ShowExceptionDialog("Import profile failed", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task ExecuteDelete()
|
private async Task ExecuteDelete()
|
||||||
{
|
{
|
||||||
if (IsNew)
|
if (IsNew)
|
||||||
|
|||||||
@ -14,15 +14,58 @@
|
|||||||
x:DataType="local:SidebarCategoryViewModel">
|
x:DataType="local:SidebarCategoryViewModel">
|
||||||
<UserControl.Resources>
|
<UserControl.Resources>
|
||||||
<converters:ColorOpacityConverter x:Key="ColorOpacityConverter" />
|
<converters:ColorOpacityConverter x:Key="ColorOpacityConverter" />
|
||||||
|
<MenuFlyout x:Key="CategoryMenuFlyout" Placement="Bottom">
|
||||||
|
<MenuItem Header="Rename" Command="{CompiledBinding RenameCategory}">
|
||||||
|
<MenuItem.Icon>
|
||||||
|
<avalonia:MaterialIcon Kind="RenameBox" />
|
||||||
|
</MenuItem.Icon>
|
||||||
|
</MenuItem>
|
||||||
|
<MenuItem Header="-" />
|
||||||
|
<MenuItem Header="Create profile" Command="{CompiledBinding AddProfile}">
|
||||||
|
<MenuItem.Icon>
|
||||||
|
<avalonia:MaterialIcon Kind="Plus" />
|
||||||
|
</MenuItem.Icon>
|
||||||
|
</MenuItem>
|
||||||
|
<MenuItem Header="Import profile" Command="{CompiledBinding ImportProfile}">
|
||||||
|
<MenuItem.Icon>
|
||||||
|
<avalonia:MaterialIcon Kind="Import" />
|
||||||
|
</MenuItem.Icon>
|
||||||
|
</MenuItem>
|
||||||
|
<MenuItem Header="-" />
|
||||||
|
<MenuItem Header="Suspend" Command="{CompiledBinding ToggleSuspended}">
|
||||||
|
<MenuItem.Icon>
|
||||||
|
<avalonia:MaterialIcon Kind="Check" IsVisible="{CompiledBinding IsSuspended}" />
|
||||||
|
</MenuItem.Icon>
|
||||||
|
</MenuItem>
|
||||||
|
<MenuItem Header="Move up" Command="{CompiledBinding MoveUp}">
|
||||||
|
<MenuItem.Icon>
|
||||||
|
<avalonia:MaterialIcon Kind="ArrowUp" />
|
||||||
|
</MenuItem.Icon>
|
||||||
|
</MenuItem>
|
||||||
|
<MenuItem Header="Move down" Command="{CompiledBinding MoveDown}">
|
||||||
|
<MenuItem.Icon>
|
||||||
|
<avalonia:MaterialIcon Kind="ArrowDown" />
|
||||||
|
</MenuItem.Icon>
|
||||||
|
</MenuItem>
|
||||||
|
<MenuItem Header="-" />
|
||||||
|
<MenuItem Header="Delete" Command="{CompiledBinding DeleteCategory}">
|
||||||
|
<MenuItem.Icon>
|
||||||
|
<avalonia:MaterialIcon Kind="TrashCan" />
|
||||||
|
</MenuItem.Icon>
|
||||||
|
</MenuItem>
|
||||||
|
</MenuFlyout>
|
||||||
</UserControl.Resources>
|
</UserControl.Resources>
|
||||||
<UserControl.Styles>
|
<UserControl.Styles>
|
||||||
<Style Selector=":is(Button).category-button">
|
<Style Selector=":is(Button).properties-button">
|
||||||
<Setter Property="IsVisible" Value="False" />
|
<Setter Property="IsVisible" Value="False" />
|
||||||
</Style>
|
</Style>
|
||||||
<Style Selector="Grid#ContainerGrid:pointerover :is(Button).category-button">
|
<Style Selector="Grid#ContainerGrid:pointerover :is(Button).properties-button">
|
||||||
<Setter Property="IsVisible" Value="True" />
|
<Setter Property="IsVisible" Value="True" />
|
||||||
</Style>
|
</Style>
|
||||||
|
<Style Selector="Grid#ContainerGrid.flyout-open :is(Button).properties-button">
|
||||||
|
<Setter Property="IsVisible" Value="True" />
|
||||||
|
</Style>
|
||||||
|
|
||||||
<Style Selector="avalonia|MaterialIcon.chevron-collapsed">
|
<Style Selector="avalonia|MaterialIcon.chevron-collapsed">
|
||||||
<Setter Property="RenderTransform" Value="rotate(180deg)" />
|
<Setter Property="RenderTransform" Value="rotate(180deg)" />
|
||||||
</Style>
|
</Style>
|
||||||
@ -89,33 +132,13 @@
|
|||||||
</Setter>
|
</Setter>
|
||||||
</Style>
|
</Style>
|
||||||
</UserControl.Styles>
|
</UserControl.Styles>
|
||||||
<Grid x:Name="ContainerGrid" Margin="0 8 0 0" RowDefinitions="Auto,*" >
|
|
||||||
<Grid.ContextFlyout>
|
<Grid Name="ContainerGrid"
|
||||||
<MenuFlyout>
|
Margin="0 8 0 0"
|
||||||
<MenuItem Header="View properties" Command="{CompiledBinding EditCategory}">
|
RowDefinitions="Auto,*"
|
||||||
<MenuItem.Icon>
|
ContextFlyout="{StaticResource CategoryMenuFlyout}"
|
||||||
<avalonia:MaterialIcon Kind="Cog" />
|
Classes.flyout-open="{Binding IsOpen, Source={StaticResource CategoryMenuFlyout}}">
|
||||||
</MenuItem.Icon>
|
<Grid Grid.Row="0" Background="Transparent" Margin="0 0 6 0" ColumnDefinitions="Auto,*,Auto,Auto,Auto">
|
||||||
</MenuItem>
|
|
||||||
<MenuItem Header="Suspend" Command="{CompiledBinding ToggleSuspended}">
|
|
||||||
<MenuItem.Icon>
|
|
||||||
<avalonia:MaterialIcon Kind="Check" IsVisible="{CompiledBinding IsSuspended}" />
|
|
||||||
</MenuItem.Icon>
|
|
||||||
</MenuItem>
|
|
||||||
<MenuItem Header="-" />
|
|
||||||
<MenuItem Header="Move up" Command="{CompiledBinding MoveUp}">
|
|
||||||
<MenuItem.Icon>
|
|
||||||
<avalonia:MaterialIcon Kind="ArrowUp" />
|
|
||||||
</MenuItem.Icon>
|
|
||||||
</MenuItem>
|
|
||||||
<MenuItem Header="Move down" Command="{CompiledBinding MoveDown}">
|
|
||||||
<MenuItem.Icon>
|
|
||||||
<avalonia:MaterialIcon Kind="ArrowDown" />
|
|
||||||
</MenuItem.Icon>
|
|
||||||
</MenuItem>
|
|
||||||
</MenuFlyout>
|
|
||||||
</Grid.ContextFlyout>
|
|
||||||
<Grid Grid.Row="0" Background="Transparent" Margin="0 0 6 0" ColumnDefinitions="Auto,*,Auto,Auto,Auto,Auto">
|
|
||||||
<avalonia:MaterialIcon Classes.chevron-collapsed="{CompiledBinding !IsCollapsed}"
|
<avalonia:MaterialIcon Classes.chevron-collapsed="{CompiledBinding !IsCollapsed}"
|
||||||
Kind="ChevronUp"
|
Kind="ChevronUp"
|
||||||
Grid.Column="0"
|
Grid.Column="0"
|
||||||
@ -162,43 +185,41 @@
|
|||||||
</Border>
|
</Border>
|
||||||
</Panel>
|
</Panel>
|
||||||
|
|
||||||
<Button Classes="category-button icon-button icon-button-small"
|
<Button Classes="properties-button icon-button icon-button-small"
|
||||||
Grid.Column="2"
|
Grid.Column="2"
|
||||||
ToolTip.Tip="Edit category"
|
|
||||||
HorizontalAlignment="Right"
|
HorizontalAlignment="Right"
|
||||||
Command="{CompiledBinding EditCategory}"
|
Flyout="{StaticResource CategoryMenuFlyout}"
|
||||||
Margin="0 0 2 0">
|
Margin="0 0 2 0">
|
||||||
<avalonia:MaterialIcon Kind="Cog" />
|
<avalonia:MaterialIcon Kind="Cog" />
|
||||||
</Button>
|
</Button>
|
||||||
<Button Classes="icon-button icon-button-small"
|
<Button Classes="icon-button icon-button-small"
|
||||||
Command="{CompiledBinding ToggleSuspended}"
|
Command="{CompiledBinding ToggleSuspended}"
|
||||||
Grid.Column="3"
|
Grid.Column="3"
|
||||||
ToolTip.Tip="Suspend/resume profile"
|
ToolTip.Tip="Suspend/resume category"
|
||||||
Margin="0 0 2 0">
|
Margin="0 0 2 0">
|
||||||
<Panel>
|
<Panel>
|
||||||
<avalonia:MaterialIcon Kind="EyeOff" IsVisible="{CompiledBinding IsSuspended}" />
|
<avalonia:MaterialIcon Kind="EyeOff" IsVisible="{CompiledBinding IsSuspended}" />
|
||||||
<avalonia:MaterialIcon Kind="Eye" IsVisible="{CompiledBinding !IsSuspended}" />
|
<avalonia:MaterialIcon Kind="Eye" IsVisible="{CompiledBinding !IsSuspended}" />
|
||||||
</Panel>
|
</Panel>
|
||||||
</Button>
|
</Button>
|
||||||
<Button Classes="category-button icon-button icon-button-small"
|
|
||||||
Grid.Column="4"
|
|
||||||
ToolTip.Tip="Add profile"
|
|
||||||
HorizontalAlignment="Right"
|
|
||||||
Command="{CompiledBinding AddProfile}"
|
|
||||||
Margin="0 0 2 0">
|
|
||||||
<avalonia:MaterialIcon Kind="Plus" />
|
|
||||||
</Button>
|
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<Border Grid.Row="1">
|
<Panel Grid.Row="1">
|
||||||
<ListBox Name="SidebarListBox"
|
<ListBox Name="SidebarListBox"
|
||||||
Classes="sidebar-listbox"
|
Classes="sidebar-listbox"
|
||||||
Items="{CompiledBinding ProfileConfigurations}"
|
Items="{CompiledBinding ProfileConfigurations}"
|
||||||
SelectedItem="{CompiledBinding SelectedProfileConfiguration}"
|
SelectedItem="{CompiledBinding SelectedProfileConfiguration}"
|
||||||
MinHeight="10"
|
MinHeight="35"
|
||||||
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
|
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
|
||||||
ScrollViewer.VerticalScrollBarVisibility="Disabled">
|
ScrollViewer.VerticalScrollBarVisibility="Disabled">
|
||||||
</ListBox>
|
</ListBox>
|
||||||
</Border>
|
<TextBlock IsVisible="{CompiledBinding !ProfileConfigurations.Count}"
|
||||||
|
Margin="12 0 0 0"
|
||||||
|
FontSize="13"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
HorizontalAlignment="Left"
|
||||||
|
IsHitTestVisible="False"
|
||||||
|
Classes="subtitle">Empty category</TextBlock>
|
||||||
|
</Panel>
|
||||||
</Grid>
|
</Grid>
|
||||||
</UserControl>
|
</UserControl>
|
||||||
@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reactive;
|
using System.Reactive;
|
||||||
using System.Reactive.Disposables;
|
using System.Reactive.Disposables;
|
||||||
@ -15,6 +16,7 @@ using Artemis.UI.Shared.Services.Builders;
|
|||||||
using Artemis.UI.Shared.Services.ProfileEditor;
|
using Artemis.UI.Shared.Services.ProfileEditor;
|
||||||
using DynamicData;
|
using DynamicData;
|
||||||
using DynamicData.Binding;
|
using DynamicData.Binding;
|
||||||
|
using Newtonsoft.Json;
|
||||||
using ReactiveUI;
|
using ReactiveUI;
|
||||||
|
|
||||||
namespace Artemis.UI.Screens.Sidebar;
|
namespace Artemis.UI.Screens.Sidebar;
|
||||||
@ -53,9 +55,11 @@ public class SidebarCategoryViewModel : ActivatableViewModelBase
|
|||||||
ToggleCollapsed = ReactiveCommand.Create(ExecuteToggleCollapsed);
|
ToggleCollapsed = ReactiveCommand.Create(ExecuteToggleCollapsed);
|
||||||
ToggleSuspended = ReactiveCommand.Create(ExecuteToggleSuspended);
|
ToggleSuspended = ReactiveCommand.Create(ExecuteToggleSuspended);
|
||||||
AddProfile = ReactiveCommand.CreateFromTask(ExecuteAddProfile);
|
AddProfile = ReactiveCommand.CreateFromTask(ExecuteAddProfile);
|
||||||
EditCategory = ReactiveCommand.CreateFromTask(ExecuteEditCategory);
|
ImportProfile = ReactiveCommand.CreateFromTask(ExecuteImportProfile);
|
||||||
MoveUp = ReactiveCommand.Create(ExecuteMoveUp);
|
MoveUp = ReactiveCommand.Create(ExecuteMoveUp);
|
||||||
MoveDown = ReactiveCommand.Create(ExecuteMoveDown);
|
MoveDown = ReactiveCommand.Create(ExecuteMoveDown);
|
||||||
|
RenameCategory = ReactiveCommand.CreateFromTask(ExecuteRenameCategory);
|
||||||
|
DeleteCategory = ReactiveCommand.CreateFromTask(ExecuteDeleteCategory);
|
||||||
|
|
||||||
this.WhenActivated(d =>
|
this.WhenActivated(d =>
|
||||||
{
|
{
|
||||||
@ -84,12 +88,17 @@ public class SidebarCategoryViewModel : ActivatableViewModelBase
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public ReactiveCommand<Unit, Unit> ImportProfile { get; }
|
||||||
|
|
||||||
public ReactiveCommand<Unit, Unit> ToggleCollapsed { get; }
|
public ReactiveCommand<Unit, Unit> ToggleCollapsed { get; }
|
||||||
public ReactiveCommand<Unit, Unit> ToggleSuspended { get; }
|
public ReactiveCommand<Unit, Unit> ToggleSuspended { get; }
|
||||||
public ReactiveCommand<Unit, Unit> AddProfile { get; }
|
public ReactiveCommand<Unit, Unit> AddProfile { get; }
|
||||||
public ReactiveCommand<Unit, Unit> EditCategory { get; }
|
|
||||||
public ReactiveCommand<Unit, Unit> MoveUp { get; }
|
public ReactiveCommand<Unit, Unit> MoveUp { get; }
|
||||||
public ReactiveCommand<Unit, Unit> MoveDown { get; }
|
public ReactiveCommand<Unit, Unit> MoveDown { get; }
|
||||||
|
public ReactiveCommand<Unit, Unit> RenameCategory { get; }
|
||||||
|
public ReactiveCommand<Unit, Unit> DeleteCategory { get; }
|
||||||
|
|
||||||
public ProfileCategory ProfileCategory { get; }
|
public ProfileCategory ProfileCategory { get; }
|
||||||
public ReadOnlyObservableCollection<SidebarProfileConfigurationViewModel> ProfileConfigurations { get; }
|
public ReadOnlyObservableCollection<SidebarProfileConfigurationViewModel> ProfileConfigurations { get; }
|
||||||
@ -114,13 +123,12 @@ public class SidebarCategoryViewModel : ActivatableViewModelBase
|
|||||||
_profileService.SaveProfileCategory(oldCategory);
|
_profileService.SaveProfileCategory(oldCategory);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task ExecuteEditCategory()
|
private async Task ExecuteRenameCategory()
|
||||||
{
|
{
|
||||||
await _windowService.CreateContentDialog()
|
await _windowService.CreateContentDialog()
|
||||||
.WithTitle("Edit category")
|
.WithTitle("Edit category")
|
||||||
.WithViewModel(out SidebarCategoryEditViewModel vm, ("category", ProfileCategory))
|
.WithViewModel(out SidebarCategoryEditViewModel vm, ("category", ProfileCategory))
|
||||||
.HavingPrimaryButton(b => b.WithText("Confirm").WithCommand(vm.Confirm))
|
.HavingPrimaryButton(b => b.WithText("Confirm").WithCommand(vm.Confirm))
|
||||||
.HavingSecondaryButton(b => b.WithText("Delete").WithCommand(vm.Delete))
|
|
||||||
.WithCloseButtonText("Cancel")
|
.WithCloseButtonText("Cancel")
|
||||||
.WithDefaultButton(ContentDialogButton.Primary)
|
.WithDefaultButton(ContentDialogButton.Primary)
|
||||||
.ShowAsync();
|
.ShowAsync();
|
||||||
@ -128,6 +136,12 @@ public class SidebarCategoryViewModel : ActivatableViewModelBase
|
|||||||
_sidebarViewModel.UpdateProfileCategories();
|
_sidebarViewModel.UpdateProfileCategories();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task ExecuteDeleteCategory()
|
||||||
|
{
|
||||||
|
if (await _windowService.ShowConfirmContentDialog($"Delete {ProfileCategory.Name}", "Do you want to delete this category and all its profiles?"))
|
||||||
|
_profileService.DeleteProfileCategory(ProfileCategory);
|
||||||
|
}
|
||||||
|
|
||||||
private async Task ExecuteAddProfile()
|
private async Task ExecuteAddProfile()
|
||||||
{
|
{
|
||||||
ProfileConfiguration? result = await _windowService.ShowDialogAsync<ProfileConfigurationEditViewModel, ProfileConfiguration?>(
|
ProfileConfiguration? result = await _windowService.ShowDialogAsync<ProfileConfigurationEditViewModel, ProfileConfiguration?>(
|
||||||
@ -140,6 +154,42 @@ public class SidebarCategoryViewModel : ActivatableViewModelBase
|
|||||||
SelectedProfileConfiguration = viewModel;
|
SelectedProfileConfiguration = viewModel;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task ExecuteImportProfile()
|
||||||
|
{
|
||||||
|
string[]? result = await _windowService.CreateOpenFileDialog()
|
||||||
|
.HavingFilter(f => f.WithExtension("json").WithName("Artemis profile"))
|
||||||
|
.ShowAsync();
|
||||||
|
|
||||||
|
if (result == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
string json = await File.ReadAllTextAsync(result[0]);
|
||||||
|
ProfileConfigurationExportModel? profileConfigurationExportModel = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
profileConfigurationExportModel = JsonConvert.DeserializeObject<ProfileConfigurationExportModel>(json, IProfileService.ExportSettings);
|
||||||
|
}
|
||||||
|
catch (JsonException e)
|
||||||
|
{
|
||||||
|
_windowService.ShowExceptionDialog("Import profile failed", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (profileConfigurationExportModel == null)
|
||||||
|
{
|
||||||
|
await _windowService.ShowConfirmContentDialog("Import profile", "Failed to import this profile, make sure it is a valid Artemis profile.", "Confirm", null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_profileService.ImportProfile(ProfileCategory, profileConfigurationExportModel);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
_windowService.ShowExceptionDialog("Import profile failed", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void ExecuteToggleCollapsed()
|
private void ExecuteToggleCollapsed()
|
||||||
{
|
{
|
||||||
|
|||||||
@ -9,13 +9,14 @@
|
|||||||
x:Class="Artemis.UI.Screens.Sidebar.SidebarProfileConfigurationView"
|
x:Class="Artemis.UI.Screens.Sidebar.SidebarProfileConfigurationView"
|
||||||
x:DataType="sidebar:SidebarProfileConfigurationViewModel"
|
x:DataType="sidebar:SidebarProfileConfigurationViewModel"
|
||||||
Background="Transparent">
|
Background="Transparent">
|
||||||
<UserControl.ContextFlyout>
|
<UserControl.Resources>
|
||||||
<MenuFlyout>
|
<MenuFlyout x:Key="ProfileMenuFlyout" Placement="Bottom">
|
||||||
<MenuItem Header="View properties" Command="{CompiledBinding EditProfile}">
|
<MenuItem Header="Edit properties" Command="{CompiledBinding EditProfile}">
|
||||||
<MenuItem.Icon>
|
<MenuItem.Icon>
|
||||||
<avalonia:MaterialIcon Kind="Cog" />
|
<avalonia:MaterialIcon Kind="Cog" />
|
||||||
</MenuItem.Icon>
|
</MenuItem.Icon>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
|
<MenuItem Header="-" />
|
||||||
<MenuItem Header="Suspend" Command="{CompiledBinding ToggleSuspended}">
|
<MenuItem Header="Suspend" Command="{CompiledBinding ToggleSuspended}">
|
||||||
<MenuItem.Icon>
|
<MenuItem.Icon>
|
||||||
<avalonia:MaterialIcon Kind="Check" IsVisible="{CompiledBinding ProfileConfiguration.IsSuspended}" />
|
<avalonia:MaterialIcon Kind="Check" IsVisible="{CompiledBinding ProfileConfiguration.IsSuspended}" />
|
||||||
@ -53,8 +54,24 @@
|
|||||||
</MenuItem.Icon>
|
</MenuItem.Icon>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
</MenuFlyout>
|
</MenuFlyout>
|
||||||
</UserControl.ContextFlyout>
|
</UserControl.Resources>
|
||||||
<Grid ColumnDefinitions="Auto,*,Auto,Auto">
|
<UserControl.Styles>
|
||||||
|
<Style Selector=":is(Button).properties-button">
|
||||||
|
<Setter Property="IsVisible" Value="False" />
|
||||||
|
</Style>
|
||||||
|
<Style Selector="Grid#ProfileContainerGrid:pointerover :is(Button).properties-button">
|
||||||
|
<Setter Property="IsVisible" Value="True" />
|
||||||
|
</Style>
|
||||||
|
<Style Selector="Grid#ProfileContainerGrid.flyout-open :is(Button).properties-button">
|
||||||
|
<Setter Property="IsVisible" Value="True" />
|
||||||
|
</Style>
|
||||||
|
</UserControl.Styles>
|
||||||
|
|
||||||
|
<Grid Name="ProfileContainerGrid"
|
||||||
|
ColumnDefinitions="Auto,*,Auto,Auto"
|
||||||
|
Background="Transparent"
|
||||||
|
ContextFlyout="{StaticResource ProfileMenuFlyout}"
|
||||||
|
Classes.flyout-open="{Binding IsOpen, Source={StaticResource ProfileMenuFlyout}}">
|
||||||
<shared:ProfileConfigurationIcon Grid.Column="0"
|
<shared:ProfileConfigurationIcon Grid.Column="0"
|
||||||
x:Name="ProfileIcon"
|
x:Name="ProfileIcon"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
@ -101,11 +118,10 @@
|
|||||||
</Border>
|
</Border>
|
||||||
</Panel>
|
</Panel>
|
||||||
|
|
||||||
<Button Command="{CompiledBinding EditProfile}"
|
<Button Classes="properties-button icon-button icon-button-small"
|
||||||
Classes="icon-button icon-button-small"
|
|
||||||
Grid.Column="2"
|
Grid.Column="2"
|
||||||
ToolTip.Tip="View properties"
|
|
||||||
HorizontalAlignment="Right"
|
HorizontalAlignment="Right"
|
||||||
|
Flyout="{StaticResource ProfileMenuFlyout}"
|
||||||
Margin="0 0 2 0">
|
Margin="0 0 2 0">
|
||||||
<avalonia:MaterialIcon Kind="Cog" />
|
<avalonia:MaterialIcon Kind="Cog" />
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user