1
0
mirror of https://github.com/Artemis-RGB/Artemis synced 2025-12-13 05:48:35 +00:00

Profile tree - Fixed moving layers into folders leaving a copy behind

Profile tree - Added rename/delete hotkeys to elements
Profile tree - Moved dialogs to the tree panel
Layer properties - Auto-select transform tool when modifying transform properties
This commit is contained in:
Robert 2020-09-17 19:45:36 +02:00
parent 375c04090b
commit a3290c40f8
25 changed files with 239 additions and 146 deletions

View File

@ -8,7 +8,7 @@
KeyframesSupported = false;
DataBindingsSupported = false;
BaseValueChanged += OnBaseValueChanged;
CurrentValueSet += OnCurrentValueSet;
}
/// <summary>
@ -25,7 +25,7 @@
throw new ArtemisCoreException("Color Gradients do not support keyframes.");
}
private void OnBaseValueChanged(object sender, LayerPropertyEventArgs<ColorGradient> e)
private void OnCurrentValueSet(object sender, LayerPropertyEventArgs<ColorGradient> e)
{
// Don't allow color gradients to be null
if (BaseValue == null)

View File

@ -157,7 +157,7 @@ namespace Artemis.Core
Transform.GroupDescription = (PropertyGroupDescriptionAttribute) transformAttribute;
Transform.Initialize(this, "Transform.", Constants.CorePluginInfo);
General.ShapeType.BaseValueChanged += ShapeTypeOnBaseValueChanged;
General.ShapeType.CurrentValueSet += ShapeTypeOnCurrentValueSet;
ApplyShapeType();
ActivateLayerBrush();
}
@ -213,7 +213,7 @@ namespace Artemis.Core
#region Shape management
private void ShapeTypeOnBaseValueChanged(object sender, EventArgs e)
private void ShapeTypeOnCurrentValueSet(object sender, EventArgs e)
{
ApplyShapeType();
}

View File

@ -15,7 +15,7 @@ namespace Artemis.Core
/// </para>
/// </summary>
/// <typeparam name="T">The type of property encapsulated in this layer property</typeparam>
public abstract class LayerProperty<T> : ILayerProperty
public class LayerProperty<T> : ILayerProperty
{
private bool _disposed;
@ -120,8 +120,7 @@ namespace Artemis.Core
_baseValue = value;
Update(0);
OnBaseValueChanged();
LayerPropertyGroup.OnLayerPropertyBaseValueChanged(new LayerPropertyEventArgs(this));
OnCurrentValueSet();
}
}
@ -165,6 +164,7 @@ namespace Artemis.Core
// Force an update so that the base value is applied to the current value and
// keyframes/data bindings are applied using the new base value
Update(0);
OnCurrentValueSet();
}
/// <summary>
@ -534,9 +534,9 @@ namespace Artemis.Core
public event EventHandler<LayerPropertyEventArgs<T>> Updated;
/// <summary>
/// Occurs when the base value of the layer property was updated
/// Occurs when the current value of the layer property was updated by some form of input
/// </summary>
public event EventHandler<LayerPropertyEventArgs<T>> BaseValueChanged;
public event EventHandler<LayerPropertyEventArgs<T>> CurrentValueSet;
/// <summary>
/// Occurs when the <see cref="IsHidden" /> value of the layer property was updated
@ -573,9 +573,10 @@ namespace Artemis.Core
Updated?.Invoke(this, new LayerPropertyEventArgs<T>(this));
}
protected virtual void OnBaseValueChanged()
protected virtual void OnCurrentValueSet()
{
BaseValueChanged?.Invoke(this, new LayerPropertyEventArgs<T>(this));
CurrentValueSet?.Invoke(this, new LayerPropertyEventArgs<T>(this));
LayerPropertyGroup.OnLayerPropertyOnCurrentValueSet(new LayerPropertyEventArgs(this));
}
protected virtual void OnVisibilityChanged()

View File

@ -274,10 +274,10 @@ namespace Artemis.Core
public event EventHandler PropertyGroupInitialized;
/// <summary>
/// Occurs when one of the base value of one of the layer properties in this group changes
/// Occurs when one of the current value of one of the layer properties in this group changes by some form of input
/// <para>Note: Will not trigger on properties in child groups</para>
/// </summary>
public event EventHandler<LayerPropertyEventArgs> LayerPropertyBaseValueChanged;
public event EventHandler<LayerPropertyEventArgs> LayerPropertyOnCurrentValueSet;
/// <summary>
/// Occurs when the <see cref="IsHidden" /> value of the layer property was updated
@ -294,9 +294,9 @@ namespace Artemis.Core
VisibilityChanged?.Invoke(this, EventArgs.Empty);
}
internal virtual void OnLayerPropertyBaseValueChanged(LayerPropertyEventArgs e)
internal virtual void OnLayerPropertyOnCurrentValueSet(LayerPropertyEventArgs e)
{
LayerPropertyBaseValueChanged?.Invoke(this, e);
LayerPropertyOnCurrentValueSet?.Invoke(this, e);
}
#endregion

View File

@ -65,6 +65,7 @@
KeyDown="InputKeyDown"
Visibility="Collapsed"
RequestBringIntoView="Input_OnRequestBringIntoView"
PreviewTextInput="Input_PreviewTextInput" />
PreviewTextInput="Input_PreviewTextInput"
DataObject.Pasting="Input_OnPasting"/>
</Grid>
</UserControl>

View File

@ -1,8 +1,6 @@
using System;
using System.ComponentModel;
using System.Globalization;
using System.Runtime.CompilerServices;
using System.Text.RegularExpressions;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
@ -18,6 +16,8 @@ namespace Artemis.UI.Shared
new FrameworkPropertyMetadata(default(float), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, FloatPropertyChangedCallback));
public static readonly DependencyProperty StepSizeProperty = DependencyProperty.Register(nameof(StepSize), typeof(float), typeof(DraggableFloat));
public static readonly DependencyProperty MinProperty = DependencyProperty.Register(nameof(Min), typeof(float?), typeof(DraggableFloat));
public static readonly DependencyProperty MaxProperty = DependencyProperty.Register(nameof(Max), typeof(float?), typeof(DraggableFloat));
public static readonly RoutedEvent ValueChangedEvent =
EventManager.RegisterRoutedEvent(
@ -49,6 +49,18 @@ namespace Artemis.UI.Shared
set => SetValue(StepSizeProperty, value);
}
public float? Min
{
get => (float?) GetValue(MinProperty);
set => SetValue(MinProperty, value);
}
public float? Max
{
get => (float?) GetValue(MaxProperty);
set => SetValue(MaxProperty, value);
}
public event PropertyChangedEventHandler PropertyChanged;
public event EventHandler DragStarted;
@ -126,7 +138,16 @@ namespace Artemis.UI.Shared
if (stepSize == 0)
stepSize = 0.1m;
Value = (float) UltimateRoundingFunction(startValue + stepSize * (x - startX), stepSize, 0.5m);
if (Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift))
stepSize = stepSize * 10;
var value = (float) UltimateRoundingFunction(startValue + stepSize * (x - startX), stepSize, 0.5m);
if (Min != null)
value = Math.Max(value, Min.Value);
if (Max != null)
value = Math.Min(value, Max.Value);
Value = value;
}
private void InputLostFocus(object sender, RoutedEventArgs e)
@ -166,9 +187,34 @@ namespace Artemis.UI.Shared
private void Input_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
var seperator = CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator;
var regex = new Regex("^[" + seperator + "][-|0-9]+$|^-?[0-9]*[" + seperator + "]{0,1}[0-9]*$");
e.Handled = !regex.IsMatch(e.Text);
e.Handled = !ValidateInput(sender, e);
}
private void Input_OnPasting(object sender, DataObjectPastingEventArgs e)
{
if (e.DataObject.GetDataPresent(typeof(string)))
{
var text = (string) e.DataObject.GetData(typeof(string));
if (!float.TryParse(text, out _))
e.CancelCommand();
}
else
e.CancelCommand();
}
// Borrowed from https://stackoverflow.com/a/48082972/5015269 because a regex approach has bad compatibility with
// different locales
private bool ValidateInput(object sender, TextCompositionEventArgs e)
{
if (!(sender is TextBox textBox))
return false;
// Use SelectionStart property to find the caret position.
// Insert the previewed text into the existing text in the textbox.
var fullText = textBox.Text.Insert(textBox.SelectionStart, e.Text);
// If parsing is successful, set Handled to false
return float.TryParse(fullText, out _);
}
private static decimal UltimateRoundingFunction(decimal amountToRound, decimal nearstOf, decimal fairness)

View File

@ -15,7 +15,7 @@ namespace Artemis.UI.Shared
LayerProperty = layerProperty;
ProfileEditorService = profileEditorService;
LayerProperty.Updated += LayerPropertyOnUpdated;
LayerProperty.BaseValueChanged += LayerPropertyOnUpdated;
LayerProperty.CurrentValueSet += LayerPropertyOnUpdated;
LayerProperty.DataBindingEnabled += LayerPropertyOnDataBindingChange;
LayerProperty.DataBindingDisabled += LayerPropertyOnDataBindingChange;
UpdateInputValue();
@ -26,7 +26,7 @@ namespace Artemis.UI.Shared
LayerProperty = layerProperty;
ProfileEditorService = profileEditorService;
LayerProperty.Updated += LayerPropertyOnUpdated;
LayerProperty.BaseValueChanged += LayerPropertyOnUpdated;
LayerProperty.CurrentValueSet += LayerPropertyOnUpdated;
LayerProperty.DataBindingEnabled += LayerPropertyOnDataBindingChange;
LayerProperty.DataBindingDisabled += LayerPropertyOnDataBindingChange;
UpdateInputValue();
@ -56,7 +56,7 @@ namespace Artemis.UI.Shared
public override void Dispose()
{
LayerProperty.Updated -= LayerPropertyOnUpdated;
LayerProperty.BaseValueChanged -= LayerPropertyOnUpdated;
LayerProperty.CurrentValueSet -= LayerPropertyOnUpdated;
LayerProperty.DataBindingEnabled -= LayerPropertyOnDataBindingChange;
LayerProperty.DataBindingDisabled -= LayerPropertyOnDataBindingChange;
Dispose(true);

View File

@ -13,11 +13,19 @@
<TextBlock Style="{StaticResource MaterialDesignHeadline6TextBlock}" 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 Orientation="Horizontal" HorizontalAlignment="Right" Margin="0 8 0 0">
<Button Style="{StaticResource MaterialDesignFlatButton}"
Focusable="False"
IsCancel="True"
Command="{s:Action Cancel}"
Content="{Binding CancelText}" />
<Button x:Name="ConfirmButton"
Style="{StaticResource MaterialDesignFlatButton}"
IsDefault="True"
Focusable="True"
Command="{s:Action Confirm}"
Content="{Binding ConfirmText}" />
</StackPanel>
</StackPanel>
</UserControl>

View File

@ -12,7 +12,7 @@ namespace Artemis.UI.Shared.Services
public interface IDialogService : IArtemisSharedUIService
{
/// <summary>
/// Shows a confirm dialog on the dialog host provided
/// Shows a confirm dialog on the main dialog host
/// </summary>
/// <param name="header">The title of the dialog</param>
/// <param name="text">The body text of the dialog</param>

View File

@ -15,6 +15,8 @@
<shared:DraggableFloat Value="{Binding InputValue}"
materialDesign:ValidationAssist.UsePopup="True"
StepSize="{Binding LayerProperty.PropertyDescription.InputStepSize}"
Max="{Binding LayerProperty.PropertyDescription.MaxInputValue}"
Min="{Binding LayerProperty.PropertyDescription.MinInputValue}"
DragStarted="{s:Action InputDragStarted}"
DragEnded="{s:Action InputDragEnded}"
IsEnabled="{Binding IsEnabled}"/>

View File

@ -15,6 +15,8 @@
<shared:DraggableFloat Value="{Binding InputValue}"
materialDesign:ValidationAssist.UsePopup="True"
StepSize="{Binding LayerProperty.PropertyDescription.InputStepSize}"
Max="{Binding LayerProperty.PropertyDescription.MaxInputValue}"
Min="{Binding LayerProperty.PropertyDescription.MinInputValue}"
DragStarted="{s:Action InputDragStarted}"
DragEnded="{s:Action InputDragEnded}"
IsEnabled="{Binding IsEnabled}"/>

View File

@ -14,6 +14,8 @@
<shared:DraggableFloat ToolTip="X-coordinate (horizontal)"
Value="{Binding X}"
StepSize="{Binding LayerProperty.PropertyDescription.InputStepSize}"
Max="{Binding LayerProperty.PropertyDescription.MaxInputValue}"
Min="{Binding LayerProperty.PropertyDescription.MinInputValue}"
DragStarted="{s:Action InputDragStarted}"
DragEnded="{s:Action InputDragEnded}"
IsEnabled="{Binding IsXEnabled}"/>
@ -21,6 +23,8 @@
<shared:DraggableFloat ToolTip="Y-coordinate (vertical)"
Value="{Binding Y}"
StepSize="{Binding LayerProperty.PropertyDescription.InputStepSize}"
Max="{Binding LayerProperty.PropertyDescription.MaxInputValue}"
Min="{Binding LayerProperty.PropertyDescription.MinInputValue}"
DragStarted="{s:Action InputDragStarted}"
DragEnded="{s:Action InputDragEnded}"
IsEnabled="{Binding IsYEnabled}"/>

View File

@ -14,6 +14,8 @@
<shared:DraggableFloat ToolTip="Height"
Value="{Binding Height}"
StepSize="{Binding LayerProperty.PropertyDescription.InputStepSize}"
Max="{Binding LayerProperty.PropertyDescription.MaxInputValue}"
Min="{Binding LayerProperty.PropertyDescription.MinInputValue}"
DragStarted="{s:Action InputDragStarted}"
DragEnded="{s:Action InputDragEnded}"
IsEnabled="{Binding IsHeightEnabled}"/>
@ -21,6 +23,8 @@
<shared:DraggableFloat ToolTip="Width"
Value="{Binding Width}"
StepSize="{Binding LayerProperty.PropertyDescription.InputStepSize}"
Max="{Binding LayerProperty.PropertyDescription.MaxInputValue}"
Min="{Binding LayerProperty.PropertyDescription.MinInputValue}"
DragStarted="{s:Action InputDragStarted}"
DragEnded="{s:Action InputDragEnded}"
IsEnabled="{Binding IsWidthEnabled}"/>

View File

@ -103,7 +103,7 @@ namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
var toRemove = Items.Where(c => !DisplayConditionGroup.Children.Contains(c.Model)).ToList();
// Using RemoveRange breaks our lovely animations
foreach (var displayConditionViewModel in toRemove)
CloseItem(displayConditionViewModel);
Items.Remove(displayConditionViewModel);
foreach (var childModel in Model.Children)
{
@ -113,18 +113,18 @@ namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
switch (childModel)
{
case DisplayConditionGroup displayConditionGroup:
ActivateItem(_displayConditionsVmFactory.DisplayConditionGroupViewModel(displayConditionGroup, IsListGroup));
Items.Add(_displayConditionsVmFactory.DisplayConditionGroupViewModel(displayConditionGroup, IsListGroup));
break;
case DisplayConditionList displayConditionListPredicate:
ActivateItem(_displayConditionsVmFactory.DisplayConditionListViewModel(displayConditionListPredicate));
Items.Add(_displayConditionsVmFactory.DisplayConditionListViewModel(displayConditionListPredicate));
break;
case DisplayConditionPredicate displayConditionPredicate:
if (!IsListGroup)
ActivateItem(_displayConditionsVmFactory.DisplayConditionPredicateViewModel(displayConditionPredicate));
Items.Add(_displayConditionsVmFactory.DisplayConditionPredicateViewModel(displayConditionPredicate));
break;
case DisplayConditionListPredicate displayConditionListPredicate:
if (IsListGroup)
ActivateItem(_displayConditionsVmFactory.DisplayConditionListPredicateViewModel(displayConditionListPredicate));
Items.Add(_displayConditionsVmFactory.DisplayConditionListPredicateViewModel(displayConditionListPredicate));
break;
}
}

View File

@ -152,7 +152,7 @@ namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
var toRemove = Items.Where(c => !DisplayConditionList.Children.Contains(c.Model)).ToList();
// Using RemoveRange breaks our lovely animations
foreach (var displayConditionViewModel in toRemove)
CloseItem(displayConditionViewModel);
Items.Remove(displayConditionViewModel);
foreach (var childModel in Model.Children)
{
@ -163,7 +163,7 @@ namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
var viewModel = _displayConditionsVmFactory.DisplayConditionGroupViewModel(displayConditionGroup, true);
viewModel.IsRootGroup = true;
ActivateItem(viewModel);
Items.Add(viewModel);
}
foreach (var childViewModel in Items)

View File

@ -39,7 +39,7 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
// Create a data binding VM for each data bindable property. These VMs will be responsible for retrieving
// and creating the actual data bindings
foreach (var registration in registrations)
ActivateItem(_dataBindingsVmFactory.DataBindingViewModel(registration));
Items.Add(_dataBindingsVmFactory.DataBindingViewModel(registration));
SelectedItemIndex = 0;
}

View File

@ -9,62 +9,67 @@
xmlns:behaviors="clr-namespace:Artemis.UI.Behaviors"
xmlns:b="http://schemas.microsoft.com/xaml/behaviors"
xmlns:profileTree1="clr-namespace:Artemis.UI.Screens.ProfileEditor.ProfileTree"
xmlns:treeItem1="clr-namespace:Artemis.UI.Screens.ProfileEditor.ProfileTree.TreeItem"
xmlns:treeItem="clr-namespace:Artemis.UI.Screens.ProfileEditor.ProfileTree.TreeItem"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
d:DataContext="{d:DesignInstance {x:Type profileTree1:ProfileTreeViewModel}}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<StackPanel>
<TextBlock Style="{StaticResource MaterialDesignSubtitle1TextBlock}" Margin="10 5 0 -4">
Profile elements
</TextBlock>
<Separator Style="{StaticResource MaterialDesignDarkSeparator}" Margin="8 0" />
</StackPanel>
<materialDesign:DialogHost IsTabStop="False" Focusable="False" Identifier="ProfileTreeDialog" DialogTheme="Inherit">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<StackPanel>
<TextBlock Style="{StaticResource MaterialDesignSubtitle1TextBlock}" Margin="10 5 0 -4">
Profile elements
</TextBlock>
<Separator Style="{StaticResource MaterialDesignDarkSeparator}" Margin="8 0" />
</StackPanel>
<TreeView Grid.Row="1"
ItemsSource="{Binding ActiveItem.Items}"
HorizontalContentAlignment="Stretch"
dd:DragDrop.IsDragSource="True"
dd:DragDrop.IsDropTarget="True"
dd:DragDrop.DropHandler="{Binding}">
<b:Interaction.Behaviors>
<behaviors:TreeViewSelectionBehavior ExpandSelected="True" SelectedItem="{Binding SelectedTreeItem}" />
</b:Interaction.Behaviors>
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type treeItem1:FolderViewModel}" ItemsSource="{Binding Items}">
<ContentControl s:View.Model="{Binding}" />
</HierarchicalDataTemplate>
<!-- TODO: Ensure this item source is required -->
<HierarchicalDataTemplate DataType="{x:Type treeItem1:LayerViewModel}" ItemsSource="{Binding Items}">
<ContentControl s:View.Model="{Binding}" />
</HierarchicalDataTemplate>
</TreeView.Resources>
</TreeView>
<TreeView Grid.Row="1"
ItemsSource="{Binding ActiveItem.Items}"
HorizontalContentAlignment="Stretch"
dd:DragDrop.IsDragSource="True"
dd:DragDrop.IsDropTarget="True"
dd:DragDrop.DropHandler="{Binding}">
<TreeView.InputBindings>
<KeyBinding Key="F2" Command="{s:Action RenameElement}" s:View.ActionTarget="{Binding SelectedTreeItem}"/>
<KeyBinding Key="Delete" Command="{s:Action DeleteElement}" s:View.ActionTarget="{Binding SelectedTreeItem}"/>
</TreeView.InputBindings>
<b:Interaction.Behaviors>
<behaviors:TreeViewSelectionBehavior ExpandSelected="True" SelectedItem="{Binding SelectedTreeItem}" />
</b:Interaction.Behaviors>
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type treeItem:FolderViewModel}" ItemsSource="{Binding Items}">
<ContentControl s:View.Model="{Binding}" />
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="{x:Type treeItem:LayerViewModel}">
<ContentControl s:View.Model="{Binding}" />
</HierarchicalDataTemplate>
</TreeView.Resources>
</TreeView>
<StackPanel HorizontalAlignment="Right" Grid.Row="2" Orientation="Horizontal" Margin="8">
<Button Style="{StaticResource MaterialDesignIconForegroundButton}"
Padding="2 0 2 0"
Width="30"
Height="30"
materialDesign:RippleAssist.IsCentered="True"
ToolTip="Add new folder to root"
Command="{s:Action AddFolder}">
<materialDesign:PackIcon Kind="CreateNewFolder" Width="15" />
</Button>
<Button Style="{StaticResource MaterialDesignIconForegroundButton}"
Width="30"
Height="30"
Padding="2 0 2 0"
materialDesign:RippleAssist.IsCentered="True"
ToolTip="Add new layer to root"
Command="{s:Action AddLayer}">
<materialDesign:PackIcon Kind="LayersPlus" Width="15" />
</Button>
</StackPanel>
</Grid>
<StackPanel HorizontalAlignment="Right" Grid.Row="2" Orientation="Horizontal" Margin="8">
<Button Style="{StaticResource MaterialDesignIconForegroundButton}"
Padding="2 0 2 0"
Width="30"
Height="30"
materialDesign:RippleAssist.IsCentered="True"
ToolTip="Add new folder to root"
Command="{s:Action AddFolder}">
<materialDesign:PackIcon Kind="CreateNewFolder" Width="15" />
</Button>
<Button Style="{StaticResource MaterialDesignIconForegroundButton}"
Width="30"
Height="30"
Padding="2 0 2 0"
materialDesign:RippleAssist.IsCentered="True"
ToolTip="Add new layer to root"
Command="{s:Action AddLayer}">
<materialDesign:PackIcon Kind="LayersPlus" Width="15" />
</Button>
</StackPanel>
</Grid>
</materialDesign:DialogHost>
</UserControl>

View File

@ -71,6 +71,8 @@ namespace Artemis.UI.Screens.ProfileEditor.ProfileTree.TreeItem
{
var sourceParent = (TreeItemViewModel) source.Parent;
var parent = (TreeItemViewModel) Parent;
// If the parents are different, remove the element from the old parent and add it to the new parent
if (source.Parent != Parent)
{
sourceParent.RemoveExistingElement(source);
@ -146,7 +148,8 @@ namespace Artemis.UI.Screens.ProfileEditor.ProfileTree.TreeItem
// ReSharper disable once UnusedMember.Global - Called from view
public async Task RenameElement()
{
var result = await _dialogService.ShowDialog<RenameViewModel>(
var result = await _dialogService.ShowDialogAt<RenameViewModel>(
"ProfileTreeDialog",
new Dictionary<string, object>
{
{"subject", ProfileElement is Folder ? "folder" : "layer"},
@ -163,9 +166,10 @@ namespace Artemis.UI.Screens.ProfileEditor.ProfileTree.TreeItem
// ReSharper disable once UnusedMember.Global - Called from view
public async Task DeleteElement()
{
var result = await _dialogService.ShowConfirmDialog(
var result = await _dialogService.ShowConfirmDialogAt(
"ProfileTreeDialog",
"Delete profile element",
"Are you sure you want to delete this element? This cannot be undone."
"Are you sure?"
);
if (!result)
@ -185,7 +189,7 @@ namespace Artemis.UI.Screens.ProfileEditor.ProfileTree.TreeItem
// Remove VMs that are no longer a child
var toRemove = Items.Where(c => c.ProfileElement.Parent != ProfileElement).ToList();
foreach (var treeItemViewModel in toRemove)
DeactivateItem(treeItemViewModel);
Items.Remove(treeItemViewModel);
// Order the children
var vmsList = Items.OrderBy(v => v.ProfileElement.Order).ToList();
@ -222,7 +226,7 @@ namespace Artemis.UI.Screens.ProfileEditor.ProfileTree.TreeItem
foreach (var treeItemViewModel in newChildren)
{
treeItemViewModel.UpdateProfileElements();
ActivateItem(treeItemViewModel);
Items.Add(treeItemViewModel);
}
}

View File

@ -31,7 +31,6 @@ namespace Artemis.UI.Screens.ProfileEditor.Visualization
private BindableCollection<ArtemisDevice> _devices;
private BindableCollection<ArtemisLed> _highlightedLeds;
private PluginSetting<bool> _highlightSelectedLayer;
private bool _isInitializing;
private PluginSetting<bool> _onlyShowSelectedShape;
private PanZoomViewModel _panZoomViewModel;
private Layer _previousSelectedLayer;
@ -67,12 +66,6 @@ namespace Artemis.UI.Screens.ProfileEditor.Visualization
eventAggregator.Subscribe(this);
}
public bool IsInitializing
{
get => _isInitializing;
private set => SetAndNotify(ref _isInitializing, value);
}
public bool CanSelectEditTool
{
get => _canSelectEditTool;
@ -375,11 +368,16 @@ namespace Artemis.UI.Screens.ProfileEditor.Visualization
private void OnProfileElementSelected(object sender, EventArgs e)
{
if (_previousSelectedLayer != null)
{
_previousSelectedLayer.LayerBrushUpdated -= SelectedLayerOnLayerBrushUpdated;
_previousSelectedLayer.Transform.LayerPropertyOnCurrentValueSet -= TransformValueChanged;
}
if (_profileEditorService.SelectedProfileElement is Layer layer)
{
_previousSelectedLayer = layer;
_previousSelectedLayer.LayerBrushUpdated += SelectedLayerOnLayerBrushUpdated;
_previousSelectedLayer.Transform.LayerPropertyOnCurrentValueSet += TransformValueChanged;
}
else
_previousSelectedLayer = null;
@ -393,6 +391,12 @@ namespace Artemis.UI.Screens.ProfileEditor.Visualization
UpdateCanSelectEditTool();
}
private void TransformValueChanged(object? sender, LayerPropertyEventArgs e)
{
if (ActiveToolIndex != 1)
ActivateToolByIndex(1);
}
private void OnSelectedProfileElementUpdated(object sender, EventArgs e)
{
ApplyActiveProfile();

View File

@ -36,7 +36,6 @@
Data="{Binding ShapeGeometry, Mode=OneWay}"
Fill="Transparent"
Stroke="{DynamicResource PrimaryHueMidBrush}"
StrokeThickness="{Binding OutlineThickness}"
StrokeDashArray="2 2"
Cursor="/Resources/Cursors/aero_drag.cur"
MouseDown="MoveOnMouseDown"

View File

@ -49,31 +49,41 @@
</Style.Triggers>
</Style>
</mde:MaterialWindow.Resources>
<materialDesign:DialogHost Identifier="RootDialog" DialogTheme="Inherit" SnackbarMessageQueue="{Binding MainMessageQueue}">
<Grid>
<materialDesign:DrawerHost IsLeftDrawerOpen="{Binding SidebarViewModel.IsSidebarOpen}">
<materialDesign:DrawerHost.LeftDrawerContent>
<ContentControl s:View.Model="{Binding SidebarViewModel}" Width="220" ClipToBounds="False" />
</materialDesign:DrawerHost.LeftDrawerContent>
<DockPanel>
<mde:AppBar Type="Dense"
IsNavigationDrawerOpen="{Binding SidebarViewModel.IsSidebarOpen, Mode=TwoWay}"
Title="{Binding ActiveItem.DisplayName}"
ShowNavigationDrawerButton="True"
DockPanel.Dock="Top">
<StackPanel>
<!-- Bug: materialDesign:RippleAssist.RippleOnTop doesn't look as nice but otherwise it doesn't work at all, not sure why -->
<Button Style="{StaticResource MaterialDesignIconForegroundButton}" ToolTip="Open debugger" Command="{s:Action ShowDebugger}"
materialDesign:RippleAssist.RippleOnTop="True">
<materialDesign:PackIcon Kind="Matrix" />
</Button>
</StackPanel>
</mde:AppBar>
<materialDesign:DialogHost IsTabStop="False"
Focusable="False"
Identifier="RootDialog"
DialogTheme="Inherit"
SnackbarMessageQueue="{Binding MainMessageQueue}">
<materialDesign:DrawerHost IsLeftDrawerOpen="{Binding SidebarViewModel.IsSidebarOpen}">
<materialDesign:DrawerHost.LeftDrawerContent>
<ContentControl s:View.Model="{Binding SidebarViewModel}" Width="220" ClipToBounds="False" />
</materialDesign:DrawerHost.LeftDrawerContent>
<DockPanel>
<mde:AppBar Type="Dense"
IsNavigationDrawerOpen="{Binding SidebarViewModel.IsSidebarOpen, Mode=TwoWay}"
Title="{Binding ActiveItem.DisplayName}"
ShowNavigationDrawerButton="True"
DockPanel.Dock="Top">
<StackPanel>
<!-- Bug: materialDesign:RippleAssist.RippleOnTop doesn't look as nice but otherwise it doesn't work at all, not sure why -->
<Button Style="{StaticResource MaterialDesignIconForegroundButton}"
ToolTip="Open debugger"
Command="{s:Action ShowDebugger}"
materialDesign:RippleAssist.RippleOnTop="True">
<materialDesign:PackIcon Kind="Matrix" />
</Button>
</StackPanel>
</mde:AppBar>
<Grid>
<ContentControl s:View.Model="{Binding ActiveItem}" Style="{StaticResource InitializingFade}" />
</DockPanel>
</materialDesign:DrawerHost>
<materialDesign:Snackbar x:Name="MainSnackbar" MessageQueue="{Binding MainMessageQueue}" materialDesign:SnackbarMessage.InlineActionButtonMaxHeight="80"
materialDesign:SnackbarMessage.ContentMaxHeight="200" />
</Grid>
<materialDesign:Snackbar x:Name="MainSnackbar"
MessageQueue="{Binding MainMessageQueue}"
materialDesign:SnackbarMessage.InlineActionButtonMaxHeight="80"
materialDesign:SnackbarMessage.ContentMaxHeight="200" />
</Grid>
</DockPanel>
</materialDesign:DrawerHost>
</materialDesign:DialogHost>
</mde:MaterialWindow>

View File

@ -19,17 +19,14 @@ namespace Artemis.Plugins.LayerBrushes.Color
public override void EnableLayerBrush()
{
Layer.RenderPropertiesUpdated += HandleShaderChange;
Properties.LayerPropertyBaseValueChanged += HandleShaderChange;
Properties.LayerPropertyOnCurrentValueSet += HandleShaderChange;
Properties.Colors.BaseValue.PropertyChanged += BaseValueOnPropertyChanged;
}
public override void DisableLayerBrush()
{
Layer.RenderPropertiesUpdated -= HandleShaderChange;
Properties.GradientType.BaseValueChanged -= HandleShaderChange;
Properties.Color.BaseValueChanged -= HandleShaderChange;
Properties.TileMode.BaseValueChanged -= HandleShaderChange;
Properties.ColorsMultiplier.BaseValueChanged -= HandleShaderChange;
Properties.LayerPropertyOnCurrentValueSet -= HandleShaderChange;
Properties.Colors.BaseValue.PropertyChanged -= BaseValueOnPropertyChanged;
_paint?.Dispose();

View File

@ -38,26 +38,26 @@ namespace Artemis.Plugins.LayerBrushes.Color.PropertyGroups
protected override void EnableProperties()
{
GradientType.BaseValueChanged += GradientTypeOnBaseValueChanged;
GradientType.CurrentValueSet += GradientTypeOnCurrentValueSet;
if (ProfileElement is Layer layer)
layer.General.ResizeMode.BaseValueChanged += ResizeModeOnBaseValueChanged;
layer.General.ResizeMode.CurrentValueSet += ResizeModeOnCurrentValueSet;
UpdateVisibility();
}
protected override void DisableProperties()
{
GradientType.BaseValueChanged -= GradientTypeOnBaseValueChanged;
GradientType.CurrentValueSet -= GradientTypeOnCurrentValueSet;
if (ProfileElement is Layer layer)
layer.General.ResizeMode.BaseValueChanged -= ResizeModeOnBaseValueChanged;
layer.General.ResizeMode.CurrentValueSet -= ResizeModeOnCurrentValueSet;
}
private void GradientTypeOnBaseValueChanged(object sender, LayerPropertyEventArgs<ColorType> e)
private void GradientTypeOnCurrentValueSet(object sender, LayerPropertyEventArgs<ColorType> e)
{
UpdateVisibility();
}
private void ResizeModeOnBaseValueChanged(object sender, LayerPropertyEventArgs<LayerResizeMode> e)
private void ResizeModeOnCurrentValueSet(object sender, LayerPropertyEventArgs<LayerResizeMode> e)
{
UpdateVisibility();
}

View File

@ -19,7 +19,7 @@ namespace Artemis.Plugins.LayerBrushes.Color.PropertyGroups
protected override void EnableProperties()
{
if (ProfileElement is Layer layer)
layer.General.ResizeMode.BaseValueChanged += ResizeModeOnBaseValueChanged;
layer.General.ResizeMode.CurrentValueSet += ResizeModeOnCurrentValueSet;
UpdateVisibility();
}
@ -27,10 +27,10 @@ namespace Artemis.Plugins.LayerBrushes.Color.PropertyGroups
protected override void DisableProperties()
{
if (ProfileElement is Layer layer)
layer.General.ResizeMode.BaseValueChanged -= ResizeModeOnBaseValueChanged;
layer.General.ResizeMode.CurrentValueSet -= ResizeModeOnCurrentValueSet;
}
private void ResizeModeOnBaseValueChanged(object sender, LayerPropertyEventArgs<LayerResizeMode> e)
private void ResizeModeOnCurrentValueSet(object sender, LayerPropertyEventArgs<LayerResizeMode> e)
{
UpdateVisibility();
}

View File

@ -44,12 +44,18 @@ namespace Artemis.Plugins.LayerBrushes.Noise
protected override void EnableProperties()
{
ColorType.BaseValueChanged += (sender, args) => UpdateVisibility();
ColorType.CurrentValueSet += ColorTypeOnCurrentValueSet;
UpdateVisibility();
}
protected override void DisableProperties()
{
ColorType.CurrentValueSet -= ColorTypeOnCurrentValueSet;
}
private void ColorTypeOnCurrentValueSet(object sender, LayerPropertyEventArgs<ColorMappingType> e)
{
UpdateVisibility();
}
private void UpdateVisibility()