1
0
mirror of https://github.com/Artemis-RGB/Artemis synced 2025-12-31 17:53:32 +00:00

Conditions - Removed animations that made the UI feel sluggish

Profile editor - Fixed effects toggle sometimes dissapearing
Property tree - Replaced TreeView with custom implementation
Property tree - Fixed minus/plus numpad keys collapsing the tree
This commit is contained in:
Robert 2020-09-25 20:19:53 +02:00
parent fa329a9048
commit a5455c26d6
17 changed files with 430 additions and 447 deletions

View File

@ -117,14 +117,14 @@
Maximum="255" /> Maximum="255" />
<!-- Checkboxes don't work inside popups inside tree views, which is where the color picker is regularly used --> <!-- Checkboxes don't work inside popups inside tree views, which is where the color picker is regularly used -->
<shared:TreeViewPopupCompatibleCheckBox Grid.Row="2" <CheckBox Grid.Row="2"
x:Name="PreviewCheckBox" x:Name="PreviewCheckBox"
Margin="10 0" Margin="10 0"
VerticalAlignment="Center" VerticalAlignment="Center"
Style="{StaticResource MaterialDesignCheckBox}" Style="{StaticResource MaterialDesignCheckBox}"
Click="PreviewCheckBoxClick"> Click="PreviewCheckBoxClick">
Preview on devices Preview on devices
</shared:TreeViewPopupCompatibleCheckBox> </CheckBox>
</Grid> </Grid>
</materialDesign:Card> </materialDesign:Card>

View File

@ -1,22 +0,0 @@
using System.Windows.Controls;
using System.Windows.Input;
namespace Artemis.UI.Shared
{
// Workaround for https://developercommunity.visualstudio.com/content/problem/190202/button-controls-hosted-in-popup-windows-do-not-wor.html
/// <inheritdoc />
public class TreeViewPopupCompatibleCheckBox : CheckBox
{
/// <inheritdoc />
protected override void OnPreviewMouseLeftButtonDown(MouseButtonEventArgs e)
{
base.OnMouseLeftButtonDown(e);
}
/// <inheritdoc />
protected override void OnPreviewMouseLeftButtonUp(MouseButtonEventArgs e)
{
base.OnMouseLeftButtonUp(e);
}
}
}

View File

@ -84,7 +84,7 @@ namespace Artemis.UI.Shared
// After the animation finishes attempt to focus the input field // After the animation finishes attempt to focus the input field
Task.Run(async () => Task.Run(async () =>
{ {
await Task.Delay(400); await Task.Delay(50);
await Execute.OnUIThreadAsync(() => View.MoveFocus(new TraversalRequest(FocusNavigationDirection.First))); await Execute.OnUIThreadAsync(() => View.MoveFocus(new TraversalRequest(FocusNavigationDirection.First)));
}); });
} }

View File

@ -21,14 +21,15 @@
</ResourceDictionary> </ResourceDictionary>
</UserControl.Resources> </UserControl.Resources>
<materialDesign:Transitioner SelectedIndex="{Binding TransitionIndex}" DefaultTransitionOrigin="0.5, 0.5" Margin="3 -4"> <Grid Margin="3 -4">
<Button Style="{StaticResource DataModelConditionButton}" <Button Style="{StaticResource DataModelConditionButton}"
Background="{Binding ButtonBrush}" Background="{Binding ButtonBrush}"
BorderBrush="{Binding ButtonBrush}" BorderBrush="{Binding ButtonBrush}"
Margin="0 4" Margin="0 4"
Command="{s:Action ActivateInputViewModel}" Command="{s:Action ActivateInputViewModel}"
HorizontalAlignment="Left" HorizontalAlignment="Left"
IsEnabled="{Binding IsEnabled}"> IsEnabled="{Binding IsEnabled}"
Visibility="{Binding InputViewModel, Converter={StaticResource NullToVisibilityConverter}, ConverterParameter=Inverted}">
<Grid> <Grid>
<StackPanel Visibility="{Binding Value, Converter={StaticResource NullToVisibilityConverter}}" Orientation="Horizontal"> <StackPanel Visibility="{Binding Value, Converter={StaticResource NullToVisibilityConverter}}" Orientation="Horizontal">
<TextBlock FontWeight="Light" <TextBlock FontWeight="Light"
@ -47,11 +48,12 @@
</Button> </Button>
<Border BorderBrush="{Binding ButtonBrush}" <Border BorderBrush="{Binding ButtonBrush}"
Background="{DynamicResource MaterialDesignPaper}" Background="{DynamicResource MaterialDesignPaper}"
Visibility="{Binding InputViewModel, Converter={StaticResource NullToVisibilityConverter}}"
CornerRadius="3" CornerRadius="3"
Padding="3" Padding="3"
HorizontalAlignment="Left" HorizontalAlignment="Left"
MinWidth="140"> MinWidth="140">
<ContentControl s:View.Model="{Binding InputViewModel}" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" /> <ContentControl s:View.Model="{Binding InputViewModel}" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" />
</Border> </Border>
</materialDesign:Transitioner> </Grid>
</UserControl> </UserControl>

View File

@ -20,7 +20,6 @@ namespace Artemis.UI.Shared.Input
private string _placeholder = "Enter a value"; private string _placeholder = "Enter a value";
private DataModelPropertyAttribute _targetDescription; private DataModelPropertyAttribute _targetDescription;
private Type _targetType; private Type _targetType;
private int _transitionIndex;
private object _value; private object _value;
private bool _isEnabled; private bool _isEnabled;
@ -45,13 +44,7 @@ namespace Artemis.UI.Shared.Input
get => _buttonBrush; get => _buttonBrush;
set => SetAndNotify(ref _buttonBrush, value); set => SetAndNotify(ref _buttonBrush, value);
} }
public int TransitionIndex
{
get => _transitionIndex;
set => SetAndNotify(ref _transitionIndex, value);
}
public DataModelDisplayViewModel DisplayViewModel public DataModelDisplayViewModel DisplayViewModel
{ {
get => _displayViewModel; get => _displayViewModel;
@ -113,7 +106,6 @@ namespace Artemis.UI.Shared.Input
public void ActivateInputViewModel() public void ActivateInputViewModel()
{ {
TransitionIndex = 1;
InputViewModel = _dataModelUIService.GetDataModelInputViewModel( InputViewModel = _dataModelUIService.GetDataModelInputViewModel(
TargetType, TargetType,
TargetDescription, TargetDescription,
@ -149,7 +141,6 @@ namespace Artemis.UI.Shared.Input
if (submitted) if (submitted)
OnValueUpdated(new DataModelInputStaticEventArgs(value)); OnValueUpdated(new DataModelInputStaticEventArgs(value));
TransitionIndex = 0;
InputViewModel = null; InputViewModel = null;
Value = value; Value = value;
} }

View File

@ -1,23 +1,23 @@
using System; using System;
using System.Globalization; using System.Globalization;
using System.Windows; using System.Windows;
using System.Windows.Controls;
using System.Windows.Data; using System.Windows.Data;
using Artemis.UI.Extensions; using Artemis.UI.Screens.ProfileEditor.LayerProperties.Tree;
namespace Artemis.UI.Converters namespace Artemis.UI.Converters
{ {
public class LeftMarginMultiplierConverter : IValueConverter public class PropertyTreeMarginConverter : IValueConverter
{ {
public double Length { get; set; } public double Length { get; set; }
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{ {
var item = value as TreeViewItem; if (value is TreeGroupViewModel treeGroupViewModel)
if (item == null) return new Thickness(Length * treeGroupViewModel.GetDepth(), 0, 0, 0);
return new Thickness(0); if (value is ITreePropertyViewModel treePropertyViewModel)
return new Thickness(Length * treePropertyViewModel.GetDepth(), 0, 0, 0);
return new Thickness(Length * item.GetDepth(), 0, 0, 0); return new Thickness(0);
} }
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)

View File

@ -54,22 +54,22 @@
Visibility="{Binding DisplayBooleanOperator, Converter={x:Static s:BoolToVisibilityConverter.Instance}, Mode=OneWay}"> Visibility="{Binding DisplayBooleanOperator, Converter={x:Static s:BoolToVisibilityConverter.Instance}, Mode=OneWay}">
<Button.ContextMenu> <Button.ContextMenu>
<ContextMenu> <ContextMenu>
<MenuItem Header="And" <MenuItem Header="And"
Command="{s:Action SelectBooleanOperator}" Command="{s:Action SelectBooleanOperator}"
CommandParameter="And" CommandParameter="And"
ToolTip="All the conditions in the group should evaluate to true" /> ToolTip="All the conditions in the group should evaluate to true" />
<MenuItem Header="Or" <MenuItem Header="Or"
Command="{s:Action SelectBooleanOperator}" Command="{s:Action SelectBooleanOperator}"
CommandParameter="Or" CommandParameter="Or"
ToolTip="Any of the conditions in the group should evaluate to true"/> ToolTip="Any of the conditions in the group should evaluate to true" />
<MenuItem Header="And not" <MenuItem Header="And not"
Command="{s:Action SelectBooleanOperator}"
CommandParameter="AndNot"
ToolTip="All the conditions in the group should evaluate to false"/>
<MenuItem Header="Or not"
Command="{s:Action SelectBooleanOperator}" Command="{s:Action SelectBooleanOperator}"
CommandParameter="OrNot" CommandParameter="AndNot"
ToolTip="Any of the conditions in the group should evaluate to false"/> ToolTip="All the conditions in the group should evaluate to false" />
<MenuItem Header="Or not"
Command="{s:Action SelectBooleanOperator}"
CommandParameter="OrNot"
ToolTip="Any of the conditions in the group should evaluate to false" />
</ContextMenu> </ContextMenu>
</Button.ContextMenu> </Button.ContextMenu>
</Button> </Button>
@ -116,7 +116,7 @@
<MenuItem.Icon> <MenuItem.Icon>
<materialDesign:PackIcon Kind="Link" /> <materialDesign:PackIcon Kind="Link" />
</MenuItem.Icon> </MenuItem.Icon>
</MenuItem> </MenuItem>
<MenuItem Header="Add self condition" <MenuItem Header="Add self condition"
ToolTip="A condition that compares with a property contained in the list" ToolTip="A condition that compares with a property contained in the list"
Command="{s:Action AddCondition}" Command="{s:Action AddCondition}"
@ -149,13 +149,7 @@
<ItemsControl Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="2" ItemsSource="{Binding Items}"> <ItemsControl Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="2" ItemsSource="{Binding Items}">
<ItemsControl.ItemTemplate> <ItemsControl.ItemTemplate>
<DataTemplate> <DataTemplate>
<materialDesign:TransitioningContent> <ContentControl s:View.Model="{Binding}" VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch" IsTabStop="False" />
<materialDesign:TransitioningContent.OpeningEffects>
<materialDesign:TransitionEffect Kind="FadeIn" />
<materialDesign:TransitionEffect Kind="SlideInFromLeft" />
</materialDesign:TransitioningContent.OpeningEffects>
<ContentControl s:View.Model="{Binding}" VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch" IsTabStop="False" />
</materialDesign:TransitioningContent>
</DataTemplate> </DataTemplate>
</ItemsControl.ItemTemplate> </ItemsControl.ItemTemplate>
</ItemsControl> </ItemsControl>

View File

@ -39,10 +39,10 @@
</Button> </Button>
<!-- Left side, the list this predicate is targeting --> <!-- Left side, the list this predicate is targeting -->
<ContentControl Grid.Row="0" <ContentControl Grid.Row="0"
Grid.Column="1" Grid.Column="1"
s:View.Model="{Binding TargetSelectionViewModel}" s:View.Model="{Binding TargetSelectionViewModel}"
VerticalContentAlignment="Stretch" VerticalContentAlignment="Stretch"
HorizontalContentAlignment="Stretch" HorizontalContentAlignment="Stretch"
IsTabStop="False" /> IsTabStop="False" />
@ -58,23 +58,23 @@
ToolTip="Change the list operator, determining how the list contents should match"> ToolTip="Change the list operator, determining how the list contents should match">
<Button.ContextMenu> <Button.ContextMenu>
<ContextMenu> <ContextMenu>
<MenuItem Header="Any" <MenuItem Header="Any"
Command="{s:Action SelectListOperator}" Command="{s:Action SelectListOperator}"
CommandParameter="Any" CommandParameter="Any"
ToolTip="Any of the list items should evaluate to true"/> ToolTip="Any of the list items should evaluate to true" />
<MenuItem Header="All" <MenuItem Header="All"
Command="{s:Action SelectListOperator}" Command="{s:Action SelectListOperator}"
CommandParameter="All" CommandParameter="All"
ToolTip="All of the list items should evaluate to true"/> ToolTip="All of the list items should evaluate to true" />
<MenuItem Header="None" <MenuItem Header="None"
Command="{s:Action SelectListOperator}" Command="{s:Action SelectListOperator}"
CommandParameter="None" CommandParameter="None"
ToolTip="None of the list items should evaluate to true"/> ToolTip="None of the list items should evaluate to true" />
<MenuItem Header="Count (NYI)" <MenuItem Header="Count (NYI)"
Command="{s:Action SelectListOperator}" Command="{s:Action SelectListOperator}"
CommandParameter="Count" CommandParameter="Count"
IsEnabled="False" IsEnabled="False"
ToolTip="A specific amount of the list items should evaluate to true"/> ToolTip="A specific amount of the list items should evaluate to true" />
</ContextMenu> </ContextMenu>
</Button.ContextMenu> </Button.ContextMenu>
</Button> </Button>
@ -82,13 +82,7 @@
<ItemsControl Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="2" ItemsSource="{Binding Items}" Margin="0 4 0 0"> <ItemsControl Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="2" ItemsSource="{Binding Items}" Margin="0 4 0 0">
<ItemsControl.ItemTemplate> <ItemsControl.ItemTemplate>
<DataTemplate> <DataTemplate>
<materialDesign:TransitioningContent> <ContentControl s:View.Model="{Binding}" VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch" IsTabStop="False" />
<materialDesign:TransitioningContent.OpeningEffects>
<materialDesign:TransitionEffect Kind="FadeIn" />
<materialDesign:TransitionEffect Kind="SlideInFromLeft" />
</materialDesign:TransitioningContent.OpeningEffects>
<ContentControl s:View.Model="{Binding}" VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch" IsTabStop="False" />
</materialDesign:TransitioningContent>
</DataTemplate> </DataTemplate>
</ItemsControl.ItemTemplate> </ItemsControl.ItemTemplate>
</ItemsControl> </ItemsControl>

View File

@ -61,6 +61,7 @@
</Setter> </Setter>
</Style> </Style>
</UserControl.Resources> </UserControl.Resources>
<UserControl.InputBindings> <UserControl.InputBindings>
<KeyBinding Command="{s:Action Play}" Key="Space" /> <KeyBinding Command="{s:Action Play}" Key="Space" />
<KeyBinding Command="{s:Action PlayFromStart}" Modifiers="Shift" Key="Space" /> <KeyBinding Command="{s:Action PlayFromStart}" Modifiers="Shift" Key="Space" />
@ -120,14 +121,14 @@
Click="{s:Action CycleRepeating}"> Click="{s:Action CycleRepeating}">
<shared:LockableToggleButton.ToolTip> <shared:LockableToggleButton.ToolTip>
<StackPanel> <StackPanel>
<StackPanel Visibility="{Binding Repeating, Converter={StaticResource BoolToVisibilityConverter}, Mode=OneWay}" > <StackPanel Visibility="{Binding Repeating, Converter={StaticResource BoolToVisibilityConverter}, Mode=OneWay}">
<TextBlock Text="Repeat entire timeline" <TextBlock Text="Repeat entire timeline"
Visibility="{Binding RepeatTimeline, Converter={StaticResource BoolToVisibilityConverter}, Mode=OneWay}" /> Visibility="{Binding RepeatTimeline, Converter={StaticResource BoolToVisibilityConverter}, Mode=OneWay}" />
<TextBlock Text="Repeat segment" <TextBlock Text="Repeat segment"
Visibility="{Binding RepeatSegment, Converter={StaticResource BoolToVisibilityConverter}, Mode=OneWay}" /> Visibility="{Binding RepeatSegment, Converter={StaticResource BoolToVisibilityConverter}, Mode=OneWay}" />
</StackPanel> </StackPanel>
<TextBlock Visibility="{Binding Repeating, Converter={x:Static s:BoolToVisibilityConverter.InverseInstance}, Mode=OneWay}">Don't repeat the timeline</TextBlock> <TextBlock Visibility="{Binding Repeating, Converter={x:Static s:BoolToVisibilityConverter.InverseInstance}, Mode=OneWay}">Don't repeat the timeline</TextBlock>
<TextBlock>This setting only applies to the editor and <Run Text="does not" FontWeight="Bold"/> affect the repeat mode during profile use</TextBlock> <TextBlock>This setting only applies to the editor and <Run Text="does not" FontWeight="Bold" /> affect the repeat mode during profile use</TextBlock>
</StackPanel> </StackPanel>
</shared:LockableToggleButton.ToolTip> </shared:LockableToggleButton.ToolTip>
<Grid> <Grid>
@ -317,13 +318,14 @@
Margin="0 -2 5 -2" Margin="0 -2 5 -2"
Padding="10 0" Padding="10 0"
Height="20" Height="20"
Width="110" Width="115"
ToolTip="Select an effect to add" ToolTip="Select an effect to add"
VerticalAlignment="Center" VerticalAlignment="Center"
Visibility="{Binding PropertyTreeVisible, Converter={x:Static s:BoolToVisibilityConverter.Instance}}" Visibility="{Binding PropertyTreeVisible, Converter={x:Static s:BoolToVisibilityConverter.Instance}}"
IsEnabled="{Binding SelectedProfileElement, Converter={StaticResource NullToBooleanConverter}}"
Command="{x:Static materialDesign:Transitioner.MoveLastCommand}" Command="{x:Static materialDesign:Transitioner.MoveLastCommand}"
CommandTarget="{Binding ElementName=TransitionCommandAnchor}"> CommandTarget="{Binding ElementName=TransitionCommandAnchor}"
Click="{s:Action ToggleEffectsViewModel}"
IsEnabled="{Binding CanToggleEffectsViewModel}">
<TextBlock FontSize="11"> <TextBlock FontSize="11">
ADD EFFECT ADD EFFECT
</TextBlock> </TextBlock>
@ -333,13 +335,15 @@
Margin="0 -2 5 -2" Margin="0 -2 5 -2"
Padding="10 0" Padding="10 0"
Height="20" Height="20"
Width="110" Width="115"
ToolTip="Show the layer/folder properties" ToolTip="Show the layer/folder properties"
VerticalAlignment="Center" VerticalAlignment="Center"
Visibility="{Binding PropertyTreeVisible, Converter={x:Static s:BoolToVisibilityConverter.InverseInstance}}" Visibility="{Binding PropertyTreeVisible, Converter={x:Static s:BoolToVisibilityConverter.InverseInstance}}"
Command="{x:Static materialDesign:Transitioner.MoveFirstCommand}" Command="{x:Static materialDesign:Transitioner.MoveFirstCommand}"
CommandTarget="{Binding ElementName=TransitionCommandAnchor}"> CommandTarget="{Binding ElementName=TransitionCommandAnchor}"
<TextBlock FontSize="11"> Click="{s:Action ToggleEffectsViewModel}"
IsEnabled="{Binding CanToggleEffectsViewModel}">
<TextBlock FontSize="10">
SHOW PROPERTIES SHOW PROPERTIES
</TextBlock> </TextBlock>
</Button> </Button>
@ -363,7 +367,6 @@
Width="110" Width="110"
ToolTip="Add a new segment to the timeline" ToolTip="Add a new segment to the timeline"
VerticalAlignment="Center" VerticalAlignment="Center"
Visibility="{Binding PropertyTreeVisible, Converter={x:Static s:BoolToVisibilityConverter.Instance}}"
IsEnabled="{Binding SelectedProfileElement, Converter={StaticResource NullToBooleanConverter}}"> IsEnabled="{Binding SelectedProfileElement, Converter={StaticResource NullToBooleanConverter}}">
<Button.Style> <Button.Style>
<Style TargetType="{x:Type Button}" BasedOn="{StaticResource MaterialDesignFlatMidBgButton}"> <Style TargetType="{x:Type Button}" BasedOn="{StaticResource MaterialDesignFlatMidBgButton}">

View File

@ -2,6 +2,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Linq; using System.Linq;
using System.Threading.Tasks;
using System.Windows; using System.Windows;
using System.Windows.Input; using System.Windows.Input;
using System.Windows.Media; using System.Windows.Media;
@ -31,6 +32,7 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties
private int _propertyTreeIndex; private int _propertyTreeIndex;
private int _rightSideIndex; private int _rightSideIndex;
private RenderProfileElement _selectedProfileElement; private RenderProfileElement _selectedProfileElement;
private DateTime _lastEffectsViewModelToggle;
public LayerPropertiesViewModel(IProfileEditorService profileEditorService, public LayerPropertiesViewModel(IProfileEditorService profileEditorService,
ICoreService coreService, ICoreService coreService,
@ -133,6 +135,8 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties
set => SetAndNotify(ref _rightSideIndex, value); set => SetAndNotify(ref _rightSideIndex, value);
} }
public bool CanToggleEffectsViewModel => SelectedProfileElement != null && DateTime.Now - _lastEffectsViewModelToggle > TimeSpan.FromMilliseconds(250);
public bool PropertyTreeVisible => PropertyTreeIndex == 0; public bool PropertyTreeVisible => PropertyTreeIndex == 0;
public RenderProfileElement SelectedProfileElement public RenderProfileElement SelectedProfileElement
@ -143,6 +147,8 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties
if (!SetAndNotify(ref _selectedProfileElement, value)) return; if (!SetAndNotify(ref _selectedProfileElement, value)) return;
NotifyOfPropertyChange(nameof(SelectedLayer)); NotifyOfPropertyChange(nameof(SelectedLayer));
NotifyOfPropertyChange(nameof(SelectedFolder)); NotifyOfPropertyChange(nameof(SelectedFolder));
NotifyOfPropertyChange(nameof(SelectedFolder));
NotifyOfPropertyChange(nameof(CanToggleEffectsViewModel));
} }
} }
@ -294,14 +300,6 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties
if (SelectedLayer.LayerBrush != null) if (SelectedLayer.LayerBrush != null)
{ {
// TODO: wat?
// Add the root group of the brush
// The root group of the brush has no attribute so let's pull one out of our sleeve
var brushDescription = new PropertyGroupDescriptionAttribute
{
Name = SelectedLayer.LayerBrush.Descriptor.DisplayName,
Description = SelectedLayer.LayerBrush.Descriptor.Description
};
_brushPropertyGroup = _layerPropertyVmFactory.LayerPropertyGroupViewModel(SelectedLayer.LayerBrush.BaseProperties); _brushPropertyGroup = _layerPropertyVmFactory.LayerPropertyGroupViewModel(SelectedLayer.LayerBrush.BaseProperties);
LayerPropertyGroups.Add(_brushPropertyGroup); LayerPropertyGroups.Add(_brushPropertyGroup);
} }
@ -327,14 +325,6 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties
if (LayerPropertyGroups.Any(l => l.LayerPropertyGroup.LayerEffect == layerEffect) || layerEffect.BaseProperties == null) if (LayerPropertyGroups.Any(l => l.LayerPropertyGroup.LayerEffect == layerEffect) || layerEffect.BaseProperties == null)
continue; continue;
// TODO: wat?
// Add the root group of the brush
// The root group of the brush has no attribute so let's pull one out of our sleeve
var brushDescription = new PropertyGroupDescriptionAttribute
{
Name = layerEffect.Descriptor.DisplayName,
Description = layerEffect.Descriptor.Description
};
LayerPropertyGroups.Add(_layerPropertyVmFactory.LayerPropertyGroupViewModel(layerEffect.BaseProperties)); LayerPropertyGroups.Add(_layerPropertyVmFactory.LayerPropertyGroupViewModel(layerEffect.BaseProperties));
} }
@ -368,6 +358,15 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties
} }
} }
public async void ToggleEffectsViewModel()
{
_lastEffectsViewModelToggle = DateTime.Now;
NotifyOfPropertyChange(nameof(CanToggleEffectsViewModel));
await Task.Delay(300);
NotifyOfPropertyChange(nameof(CanToggleEffectsViewModel));
}
#endregion #endregion
#region Drag and drop #region Drag and drop

View File

@ -8,194 +8,246 @@
xmlns:s="https://github.com/canton7/Stylet" xmlns:s="https://github.com/canton7/Stylet"
xmlns:converters="clr-namespace:Artemis.UI.Converters" xmlns:converters="clr-namespace:Artemis.UI.Converters"
xmlns:dd="urn:gong-wpf-dragdrop" xmlns:dd="urn:gong-wpf-dragdrop"
xmlns:layerProperties="clr-namespace:Artemis.UI.Screens.ProfileEditor.LayerProperties"
mc:Ignorable="d" mc:Ignorable="d"
d:DataContext="{d:DesignInstance local:TreeGroupViewModel}" d:DataContext="{d:DesignInstance local:TreeGroupViewModel}"
d:DesignHeight="450" d:DesignWidth="800"> d:DesignHeight="450" d:DesignWidth="800">
<UserControl.Resources> <UserControl.Resources>
<converters:NullToVisibilityConverter x:Key="NullToVisibilityConverter" /> <converters:NullToVisibilityConverter x:Key="NullToVisibilityConverter" />
<converters:PropertyTreeMarginConverter Length="20" x:Key="PropertyTreeMarginConverter" />
</UserControl.Resources> </UserControl.Resources>
<StackPanel> <StackPanel>
<!-- Type: None --> <Border Name="Bd"
<TextBlock BorderBrush="{DynamicResource MaterialDesignDivider}"
dd:DragDrop.DragSourceIgnore="True" BorderThickness="0,0,0,1"
Text="{Binding LayerPropertyGroup.GroupDescription.Name}" Height="25">
ToolTip="{Binding LayerPropertyGroup.GroupDescription.Description}" <Grid Margin="{Binding Converter={StaticResource PropertyTreeMarginConverter}}">
VerticalAlignment="Center" <Grid.ColumnDefinitions>
HorizontalAlignment="Left" <ColumnDefinition Width="19" />
Margin="3 5 0 5"> <ColumnDefinition />
<TextBlock.Style> </Grid.ColumnDefinitions>
<Style TargetType="{x:Type TextBlock}"> <ToggleButton x:Name="Expander"
<Setter Property="Visibility" Value="Collapsed" /> Foreground="{DynamicResource MaterialDesignBody}"
<Style.Triggers> Style="{StaticResource MaterialDesignExpandCollapseToggleStyle}"
<DataTrigger Binding="{Binding GroupType}" Value="None"> IsChecked="{Binding Path=LayerPropertyGroupViewModel.IsExpanded}"
<Setter Property="Visibility" Value="Visible" /> ClickMode="Press" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
<!-- Type: General --> <StackPanel Grid.Column="1">
<StackPanel Orientation="Horizontal" Margin="0 5" dd:DragDrop.DragSourceIgnore="True"> <!-- Type: None -->
<StackPanel.Style> <TextBlock
<Style TargetType="{x:Type StackPanel}"> dd:DragDrop.DragSourceIgnore="True"
<Setter Property="Visibility" Value="Collapsed" /> Text="{Binding LayerPropertyGroup.GroupDescription.Name}"
<Style.Triggers> ToolTip="{Binding LayerPropertyGroup.GroupDescription.Description}"
<DataTrigger Binding="{Binding GroupType}" Value="General">
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>
</StackPanel.Style>
<materialDesign:PackIcon Kind="HammerWrench" Margin="0 -1 5 0" />
<TextBlock ToolTip="{Binding LayerPropertyGroup.GroupDescription.Description}">General</TextBlock>
</StackPanel>
<!-- Type: Transform -->
<StackPanel Orientation="Horizontal" Margin="0 5" dd:DragDrop.DragSourceIgnore="True">
<StackPanel.Style>
<Style TargetType="{x:Type StackPanel}">
<Setter Property="Visibility" Value="Collapsed" />
<Style.Triggers>
<DataTrigger Binding="{Binding GroupType}" Value="Transform">
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>
</StackPanel.Style>
<materialDesign:PackIcon Kind="TransitConnectionVariant" Margin="0 -1 5 0" />
<TextBlock ToolTip="{Binding LayerPropertyGroup.GroupDescription.Description}">Transform</TextBlock>
</StackPanel>
<!-- Type: LayerBrushRoot -->
<Grid dd:DragDrop.DragSourceIgnore="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.Style>
<Style TargetType="{x:Type Grid}">
<Setter Property="Visibility" Value="Collapsed" />
<Style.Triggers>
<DataTrigger Binding="{Binding GroupType}" Value="LayerBrushRoot">
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>
</Grid.Style>
<materialDesign:PackIcon Grid.Column="0"
Kind="{Binding LayerPropertyGroup.LayerBrush.Descriptor.Icon}"
Margin="0 5 5 0" />
<TextBlock Grid.Column="1"
ToolTip="{Binding LayerPropertyGroup.LayerBrush.Descriptor.Description}"
Margin="0 5 0 0">
Brush -&#160;
</TextBlock>
<TextBlock Grid.Column="2"
Text="{Binding LayerPropertyGroup.LayerBrush.Descriptor.DisplayName}"
ToolTip="{Binding LayerPropertyGroup.LayerBrush.Descriptor.Description}"
Margin="0 5 0 0" />
<Button Grid.Column="3"
Style="{StaticResource MaterialDesignIconButton}"
ToolTip="Open brush settings"
Width="24"
Height="24"
VerticalAlignment="Center"
HorizontalAlignment="Right"
Command="{s:Action OpenBrushSettings}"
Visibility="{Binding LayerPropertyGroup.LayerBrush.ConfigurationDialog, Converter={StaticResource NullToVisibilityConverter}}">
<materialDesign:PackIcon Kind="Settings" Height="16" Width="16" />
</Button>
</Grid>
<!-- Type: LayerEffectRoot -->
<Grid Height="24">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.Style>
<Style TargetType="{x:Type Grid}">
<Setter Property="Visibility" Value="Collapsed" />
<Style.Triggers>
<DataTrigger Binding="{Binding GroupType}" Value="LayerEffectRoot">
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>
</Grid.Style>
<materialDesign:PackIcon
Grid.Column="0"
Cursor="SizeNS"
Kind="{Binding LayerPropertyGroup.LayerEffect.Descriptor.Icon}"
Margin="0 5 5 0"
Background="Transparent" />
<TextBlock Grid.Column="1" ToolTip="{Binding LayerPropertyGroup.LayerEffect.Descriptor.Description}" Margin="0 5 0 0">
Effect
</TextBlock>
<TextBlock Grid.Column="2"
ToolTip="{Binding LayerPropertyGroup.LayerEffect.Descriptor.Description}"
Margin="3 5">
-
</TextBlock>
<!-- Show either the descriptors display name or, if set, the effect name -->
<TextBlock Grid.Column="3"
Text="{Binding LayerPropertyGroup.LayerEffect.Descriptor.DisplayName}"
ToolTip="{Binding LayerPropertyGroup.LayerEffect.Descriptor.Description}"
Margin="0 5"
Visibility="{Binding LayerPropertyGroup.LayerEffect.Name, Converter={StaticResource NullToVisibilityConverter}, ConverterParameter=Inverted}" />
<TextBlock Grid.Column="4"
Text="{Binding LayerPropertyGroup.LayerEffect.Name}"
ToolTip="{Binding LayerPropertyGroup.LayerEffect.Descriptor.Description}"
Margin="0 5"
Visibility="{Binding LayerPropertyGroup.LayerEffect.Name, Converter={StaticResource NullToVisibilityConverter}}" />
<StackPanel Grid.Column="5" Orientation="Horizontal">
<ToggleButton
Style="{StaticResource MaterialDesignFlatToggleButton}"
ToolTip="Toggle enabled state"
Width="18"
Height="18"
IsChecked="{Binding LayerPropertyGroup.LayerEffect.Enabled}"
VerticalAlignment="Center" Padding="-25"
Margin="5 0"
Command="{s:Action EnableToggled}">
<materialDesign:PackIcon Kind="Eye" Height="13" Width="13" />
</ToggleButton>
<Button Style="{StaticResource MaterialDesignIconButton}"
ToolTip="Rename"
Width="24"
Height="24"
VerticalAlignment="Center" VerticalAlignment="Center"
Command="{s:Action RenameEffect}"> HorizontalAlignment="Left"
<materialDesign:PackIcon Kind="RenameBox" Height="16" Width="16" /> Margin="3 5 0 5">
</Button> <TextBlock.Style>
<Button Style="{StaticResource MaterialDesignIconButton}" <Style TargetType="{x:Type TextBlock}">
ToolTip="Open effect settings" <Setter Property="Visibility" Value="Collapsed" />
Width="24" <Style.Triggers>
Height="24" <DataTrigger Binding="{Binding GroupType}" Value="None">
VerticalAlignment="Center" <Setter Property="Visibility" Value="Visible" />
Command="{s:Action OpenEffectSettings}" </DataTrigger>
Visibility="{Binding LayerPropertyGroup.LayerEffect.ConfigurationDialog, Converter={StaticResource NullToVisibilityConverter}}"> </Style.Triggers>
<materialDesign:PackIcon Kind="Settings" Height="16" Width="16" /> </Style>
</Button> </TextBlock.Style>
<Button Style="{StaticResource MaterialDesignIconButton}" </TextBlock>
ToolTip="Remove"
Width="24" <!-- Type: General -->
Height="24" <StackPanel Orientation="Horizontal" Margin="0 5" dd:DragDrop.DragSourceIgnore="True">
VerticalAlignment="Center" <StackPanel.Style>
Command="{s:Action DeleteEffect}"> <Style TargetType="{x:Type StackPanel}">
<materialDesign:PackIcon Kind="TrashCan" Height="16" Width="16" /> <Setter Property="Visibility" Value="Collapsed" />
</Button> <Style.Triggers>
</StackPanel> <DataTrigger Binding="{Binding GroupType}" Value="General">
</Grid> <Setter Property="Visibility" Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>
</StackPanel.Style>
<materialDesign:PackIcon Kind="HammerWrench" Margin="0 -1 5 0" />
<TextBlock ToolTip="{Binding LayerPropertyGroup.GroupDescription.Description}">General</TextBlock>
</StackPanel>
<!-- Type: Transform -->
<StackPanel Orientation="Horizontal" Margin="0 5" dd:DragDrop.DragSourceIgnore="True">
<StackPanel.Style>
<Style TargetType="{x:Type StackPanel}">
<Setter Property="Visibility" Value="Collapsed" />
<Style.Triggers>
<DataTrigger Binding="{Binding GroupType}" Value="Transform">
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>
</StackPanel.Style>
<materialDesign:PackIcon Kind="TransitConnectionVariant" Margin="0 -1 5 0" />
<TextBlock ToolTip="{Binding LayerPropertyGroup.GroupDescription.Description}">Transform</TextBlock>
</StackPanel>
<!-- Type: LayerBrushRoot -->
<Grid dd:DragDrop.DragSourceIgnore="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.Style>
<Style TargetType="{x:Type Grid}">
<Setter Property="Visibility" Value="Collapsed" />
<Style.Triggers>
<DataTrigger Binding="{Binding GroupType}" Value="LayerBrushRoot">
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>
</Grid.Style>
<materialDesign:PackIcon Grid.Column="0"
Kind="{Binding LayerPropertyGroup.LayerBrush.Descriptor.Icon}"
Margin="0 5 5 0" />
<TextBlock Grid.Column="1"
ToolTip="{Binding LayerPropertyGroup.LayerBrush.Descriptor.Description}"
Margin="0 5 0 0">
Brush -&#160;
</TextBlock>
<TextBlock Grid.Column="2"
Text="{Binding LayerPropertyGroup.LayerBrush.Descriptor.DisplayName}"
ToolTip="{Binding LayerPropertyGroup.LayerBrush.Descriptor.Description}"
Margin="0 5 0 0" />
<Button Grid.Column="3"
Style="{StaticResource MaterialDesignIconButton}"
ToolTip="Open brush settings"
Width="24"
Height="24"
VerticalAlignment="Center"
HorizontalAlignment="Right"
Command="{s:Action OpenBrushSettings}"
Visibility="{Binding LayerPropertyGroup.LayerBrush.ConfigurationDialog, Converter={StaticResource NullToVisibilityConverter}}">
<materialDesign:PackIcon Kind="Settings" Height="16" Width="16" />
</Button>
</Grid>
<!-- Type: LayerEffectRoot -->
<Grid Height="24">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.Style>
<Style TargetType="{x:Type Grid}">
<Setter Property="Visibility" Value="Collapsed" />
<Style.Triggers>
<DataTrigger Binding="{Binding GroupType}" Value="LayerEffectRoot">
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>
</Grid.Style>
<materialDesign:PackIcon
Grid.Column="0"
Cursor="SizeNS"
Kind="{Binding LayerPropertyGroup.LayerEffect.Descriptor.Icon}"
Margin="0 5 5 0"
Background="Transparent" />
<TextBlock Grid.Column="1" ToolTip="{Binding LayerPropertyGroup.LayerEffect.Descriptor.Description}" Margin="0 5 0 0">
Effect
</TextBlock>
<TextBlock Grid.Column="2"
ToolTip="{Binding LayerPropertyGroup.LayerEffect.Descriptor.Description}"
Margin="3 5">
-
</TextBlock>
<!-- Show either the descriptors display name or, if set, the effect name -->
<TextBlock Grid.Column="3"
Text="{Binding LayerPropertyGroup.LayerEffect.Descriptor.DisplayName}"
ToolTip="{Binding LayerPropertyGroup.LayerEffect.Descriptor.Description}"
Margin="0 5"
Visibility="{Binding LayerPropertyGroup.LayerEffect.Name, Converter={StaticResource NullToVisibilityConverter}, ConverterParameter=Inverted}" />
<TextBlock Grid.Column="4"
Text="{Binding LayerPropertyGroup.LayerEffect.Name}"
ToolTip="{Binding LayerPropertyGroup.LayerEffect.Descriptor.Description}"
Margin="0 5"
Visibility="{Binding LayerPropertyGroup.LayerEffect.Name, Converter={StaticResource NullToVisibilityConverter}}" />
<StackPanel Grid.Column="5" Orientation="Horizontal">
<ToggleButton
Style="{StaticResource MaterialDesignFlatToggleButton}"
ToolTip="Toggle enabled state"
Width="18"
Height="18"
IsChecked="{Binding LayerPropertyGroup.LayerEffect.Enabled}"
VerticalAlignment="Center" Padding="-25"
Margin="5 0"
Command="{s:Action EnableToggled}">
<materialDesign:PackIcon Kind="Eye" Height="13" Width="13" />
</ToggleButton>
<Button Style="{StaticResource MaterialDesignIconButton}"
ToolTip="Rename"
Width="24"
Height="24"
VerticalAlignment="Center"
Command="{s:Action RenameEffect}">
<materialDesign:PackIcon Kind="RenameBox" Height="16" Width="16" />
</Button>
<Button Style="{StaticResource MaterialDesignIconButton}"
ToolTip="Open effect settings"
Width="24"
Height="24"
VerticalAlignment="Center"
Command="{s:Action OpenEffectSettings}"
Visibility="{Binding LayerPropertyGroup.LayerEffect.ConfigurationDialog, Converter={StaticResource NullToVisibilityConverter}}">
<materialDesign:PackIcon Kind="Settings" Height="16" Width="16" />
</Button>
<Button Style="{StaticResource MaterialDesignIconButton}"
ToolTip="Remove"
Width="24"
Height="24"
VerticalAlignment="Center"
Command="{s:Action DeleteEffect}">
<materialDesign:PackIcon Kind="TrashCan" Height="16" Width="16" />
</Button>
</StackPanel>
</Grid>
</StackPanel>
</Grid>
</Border>
<!--
Do not bind directly to the LayerPropertyGroupViewModel.Children collection
Instead use a reference provided by the VM that is null when collapsed, virtualization for noobs
-->
<ItemsControl ItemsSource="{Binding Children}"
Visibility="{Binding LayerPropertyGroupViewModel.IsExpanded, Converter={x:Static s:BoolToVisibilityConverter.Instance}, Mode=OneWay}"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Stretch">
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="VerticalAlignment" Value="Stretch" />
<Setter Property="HorizontalAlignment" Value="Stretch" />
</Style>
</ItemsControl.ItemContainerStyle>
<ItemsControl.Resources>
<DataTemplate DataType="{x:Type layerProperties:LayerPropertyGroupViewModel}">
<ContentControl s:View.Model="{Binding TreeGroupViewModel}"
IsTabStop="False"
HorizontalAlignment="Stretch"
Visibility="{Binding IsVisible, Converter={x:Static s:BoolToVisibilityConverter.Instance}, Mode=OneWay}" />
</DataTemplate>
<DataTemplate DataType="{x:Type layerProperties:LayerPropertyViewModel}">
<ContentControl s:View.Model="{Binding TreePropertyViewModel}"
IsTabStop="False"
HorizontalAlignment="Stretch"
Visibility="{Binding IsVisible, Converter={x:Static s:BoolToVisibilityConverter.Instance}, Mode=OneWay}" />
</DataTemplate>
</ItemsControl.Resources>
</ItemsControl>
</StackPanel> </StackPanel>
</UserControl> </UserControl>

View File

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel;
using System.Linq; using System.Linq;
using Artemis.Core; using Artemis.Core;
using Artemis.Core.LayerBrushes; using Artemis.Core.LayerBrushes;
@ -36,6 +37,8 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.Tree
LayerPropertyGroupViewModel = layerPropertyGroupViewModel; LayerPropertyGroupViewModel = layerPropertyGroupViewModel;
LayerPropertyGroup = LayerPropertyGroupViewModel.LayerPropertyGroup; LayerPropertyGroup = LayerPropertyGroupViewModel.LayerPropertyGroup;
LayerPropertyGroupViewModel.PropertyChanged += LayerPropertyGroupViewModelOnPropertyChanged;
DetermineGroupType(); DetermineGroupType();
} }
@ -43,6 +46,11 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.Tree
public LayerPropertyGroup LayerPropertyGroup { get; } public LayerPropertyGroup LayerPropertyGroup { get; }
public LayerPropertyGroupType GroupType { get; set; } public LayerPropertyGroupType GroupType { get; set; }
public BindableCollection<PropertyChangedBase> Children =>
LayerPropertyGroupViewModel.IsExpanded && LayerPropertyGroupViewModel.IsVisible
? LayerPropertyGroupViewModel.Children
: null;
public void OpenBrushSettings() public void OpenBrushSettings()
{ {
var layerBrush = LayerPropertyGroup.LayerBrush; var layerBrush = LayerPropertyGroup.LayerBrush;
@ -128,6 +136,25 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.Tree
_profileEditorService.UpdateSelectedProfile(); _profileEditorService.UpdateSelectedProfile();
} }
public double GetDepth()
{
var depth = 0;
var current = LayerPropertyGroup.Parent;
while (current != null)
{
depth++;
current = current.Parent;
}
return depth;
}
private void LayerPropertyGroupViewModelOnPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == nameof(LayerPropertyGroupViewModel.IsExpanded) || e.PropertyName == nameof(LayerPropertyGroupViewModel.IsVisible))
NotifyOfPropertyChange(nameof(Children));
}
private void DetermineGroupType() private void DetermineGroupType()
{ {
if (LayerPropertyGroup is LayerGeneralProperties) if (LayerPropertyGroup is LayerGeneralProperties)

View File

@ -6,55 +6,67 @@
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:s="https://github.com/canton7/Stylet" xmlns:s="https://github.com/canton7/Stylet"
xmlns:shared="clr-namespace:Artemis.UI.Shared;assembly=Artemis.UI.Shared" xmlns:shared="clr-namespace:Artemis.UI.Shared;assembly=Artemis.UI.Shared"
xmlns:converters="clr-namespace:Artemis.UI.Converters"
mc:Ignorable="d" mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"> d:DesignHeight="450" d:DesignWidth="800">
<Grid Height="22" Margin="-20 0 0 0"> <UserControl.Resources>
<Grid.ColumnDefinitions> <converters:NullToVisibilityConverter x:Key="NullToVisibilityConverter" />
<ColumnDefinition Width="Auto" /> <converters:PropertyTreeMarginConverter Length="20" x:Key="PropertyTreeMarginConverter" />
<ColumnDefinition Width="*" /> </UserControl.Resources>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<ToggleButton Grid.Column="0"
Style="{StaticResource MaterialDesignFlatToggleButton}"
ToolTip="Toggle key-framing"
Width="18"
Height="18"
IsChecked="{Binding KeyframesEnabled}"
IsEnabled="{Binding LayerProperty.KeyframesSupported}"
VerticalAlignment="Center" Padding="-25">
<materialDesign:PackIcon Kind="Stopwatch" Height="13" Width="13" />
</ToggleButton>
<TextBlock Grid.Column="1" <Border Name="Bd"
Margin="5,0,0,0" BorderBrush="{DynamicResource MaterialDesignDivider}"
Padding="0,0,5,0" BorderThickness="0,0,0,1"
VerticalAlignment="Center" Height="25">
TextTrimming="CharacterEllipsis" <Grid Margin="{Binding Converter={StaticResource PropertyTreeMarginConverter}}">
Text="{Binding LayerProperty.PropertyDescription.Name}" <Grid.ColumnDefinitions>
ToolTip="{Binding LayerProperty.PropertyDescription.Description}" <ColumnDefinition Width="Auto" />
HorizontalAlignment="Left" /> <ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<ToggleButton Grid.Column="0"
Style="{StaticResource MaterialDesignFlatToggleButton}"
ToolTip="Toggle key-framing"
Width="18"
Height="18"
IsChecked="{Binding KeyframesEnabled}"
IsEnabled="{Binding LayerProperty.KeyframesSupported}"
VerticalAlignment="Center" Padding="-25">
<materialDesign:PackIcon Kind="Stopwatch" Height="13" Width="13" />
</ToggleButton>
<ContentControl Grid.Column="2" Margin="20 0" s:View.Model="{Binding PropertyInputViewModel}"> <TextBlock Grid.Column="1"
<ContentControl.Resources> Margin="5,0,0,0"
<Style TargetType="TextBlock"> Padding="0,0,5,0"
<Setter Property="Margin" Value="0 0 5 4" /> VerticalAlignment="Center"
<Setter Property="VerticalAlignment" Value="Bottom" /> TextTrimming="CharacterEllipsis"
</Style> Text="{Binding LayerProperty.PropertyDescription.Name}"
</ContentControl.Resources> ToolTip="{Binding LayerProperty.PropertyDescription.Description}"
</ContentControl> HorizontalAlignment="Left" />
<shared:LockableToggleButton Grid.Column="3" <ContentControl Grid.Column="2" Margin="20 0" s:View.Model="{Binding PropertyInputViewModel, IsAsync=True}">
Style="{StaticResource MaterialDesignFlatToggleButton}" <ContentControl.Resources>
ToolTip="Change the property's data binding" <Style TargetType="TextBlock">
Width="20" <Setter Property="Margin" Value="0 0 5 4" />
Height="20" <Setter Property="VerticalAlignment" Value="Bottom" />
VerticalAlignment="Center" </Style>
IsLocked="True" </ContentControl.Resources>
IsEnabled="{Binding LayerProperty.DataBindingsSupported}" </ContentControl>
IsChecked="{Binding HasDataBinding, Mode=OneWay}"
Click="{s:Action ActivateDataBindingViewModel}"> <shared:LockableToggleButton Grid.Column="3"
<materialDesign:PackIcon Kind="VectorLink" Height="13" Width="13" /> Style="{StaticResource MaterialDesignFlatToggleButton}"
</shared:LockableToggleButton> ToolTip="Change the property's data binding"
</Grid> Width="20"
Height="20"
VerticalAlignment="Center"
IsLocked="True"
IsEnabled="{Binding LayerProperty.DataBindingsSupported}"
IsChecked="{Binding HasDataBinding, Mode=OneWay}"
Click="{s:Action ActivateDataBindingViewModel}">
<materialDesign:PackIcon Kind="VectorLink" Height="13" Width="13" />
</shared:LockableToggleButton>
</Grid>
</Border>
</UserControl> </UserControl>

View File

@ -37,6 +37,18 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.Tree
} }
public bool HasDataBinding => LayerProperty.HasDataBinding; public bool HasDataBinding => LayerProperty.HasDataBinding;
public double GetDepth()
{
var depth = 0;
var current = LayerProperty.LayerPropertyGroup;
while (current != null)
{
depth++;
current = current.Parent;
}
return depth;
}
public bool HasPropertyInputViewModel => PropertyInputViewModel != null; public bool HasPropertyInputViewModel => PropertyInputViewModel != null;
@ -112,5 +124,6 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.Tree
{ {
bool HasPropertyInputViewModel { get; } bool HasPropertyInputViewModel { get; }
bool HasDataBinding { get; } bool HasDataBinding { get; }
double GetDepth();
} }
} }

View File

@ -11,104 +11,19 @@
mc:Ignorable="d" mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800" d:DesignHeight="450" d:DesignWidth="800"
d:DataContext="{d:DesignInstance {x:Type tree:TreeViewModel}}"> d:DataContext="{d:DesignInstance {x:Type tree:TreeViewModel}}">
<UserControl.Resources> <ItemsControl ItemsSource="{Binding LayerPropertyGroups}"
<Style x:Key="PropertyTreeStyle" TargetType="{x:Type TreeViewItem}"> VirtualizingStackPanel.IsVirtualizing="True"
<Setter Property="Background" Value="Transparent" /> VirtualizingStackPanel.VirtualizationMode="Recycling"
<Setter Property="BorderBrush" Value="{x:Null}" /> HorizontalContentAlignment="Stretch"
<Setter Property="BorderThickness" Value="0" /> HorizontalAlignment="Stretch"
<Setter Property="Foreground" Value="{DynamicResource MaterialDesignBody}" /> Background="{DynamicResource MaterialDesignToolBarBackground}"
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto" /> dd:DragDrop.IsDragSource="True"
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto" /> dd:DragDrop.IsDropTarget="True"
<Setter Property="ScrollViewer.PanningMode" Value="Both" /> dd:DragDrop.DropHandler="{Binding LayerPropertiesViewModel}">
<Setter Property="Stylus.IsFlicksEnabled" Value="False" /> <ItemsControl.ItemTemplate>
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TreeViewItem}">
<ControlTemplate.Resources>
<converters:LeftMarginMultiplierConverter Length="19" x:Key="lengthConverter" />
</ControlTemplate.Resources>
<StackPanel>
<Border Name="Bd"
Background="{TemplateBinding Background}"
BorderBrush="{DynamicResource MaterialDesignDivider}"
BorderThickness="0,0,0,1"
Height="25"
Padding="{TemplateBinding Padding}">
<Grid Margin="{Binding Converter={StaticResource lengthConverter}, RelativeSource={RelativeSource TemplatedParent}}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="19" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<ToggleButton x:Name="Expander"
Foreground="{DynamicResource MaterialDesignBody}"
Style="{StaticResource MaterialDesignExpandCollapseToggleStyle}"
IsChecked="{Binding Path=IsExpanded, RelativeSource={RelativeSource TemplatedParent}}"
ClickMode="Press" />
<ContentPresenter x:Name="PART_Header"
Grid.Column="1"
ContentSource="Header"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" />
</Grid>
</Border>
<ItemsPresenter x:Name="ItemsHost" />
</StackPanel>
<ControlTemplate.Triggers>
<Trigger Property="IsExpanded" Value="false">
<Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger>
<Trigger Property="HasItems" Value="false">
<Setter TargetName="Expander" Property="Visibility" Value="Hidden" />
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="HasHeader" Value="false" />
<Condition Property="Width" Value="Auto" />
</MultiTrigger.Conditions>
<Setter TargetName="PART_Header" Property="MinWidth" Value="75" />
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="HasHeader" Value="false" />
<Condition Property="Height" Value="Auto" />
</MultiTrigger.Conditions>
<Setter TargetName="PART_Header" Property="MinHeight" Value="19" />
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<TreeView ItemsSource="{Binding LayerPropertyGroups}"
VirtualizingStackPanel.IsVirtualizing="True"
VirtualizingStackPanel.VirtualizationMode="Recycling"
HorizontalContentAlignment="Stretch"
Background="{DynamicResource MaterialDesignToolBarBackground}"
PreviewMouseWheel="{s:Action PropertyTreePreviewMouseWheel}"
dd:DragDrop.IsDragSource="True"
dd:DragDrop.IsDropTarget="True"
dd:DragDrop.DropHandler="{Binding LayerPropertiesViewModel}"
Margin="0 -1">
<TreeView.ItemContainerStyle>
<Style TargetType="TreeViewItem" BasedOn="{StaticResource PropertyTreeStyle}">
<Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}" />
<Setter Property="Visibility" Value="{Binding IsVisible, Converter={x:Static s:BoolToVisibilityConverter.Instance}, Mode=OneWay}" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsHighlighted, Mode=OneWay}" Value="True">
<Setter Property="Background" Value="{DynamicResource MaterialDesignPaper}" />
</DataTrigger>
</Style.Triggers>
</Style>
</TreeView.ItemContainerStyle>
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type local:LayerPropertyGroupViewModel}" ItemsSource="{Binding Children}"> <HierarchicalDataTemplate DataType="{x:Type local:LayerPropertyGroupViewModel}" ItemsSource="{Binding Children}">
<ContentControl s:View.Model="{Binding TreeGroupViewModel}" /> <ContentControl s:View.Model="{Binding TreeGroupViewModel}" />
</HierarchicalDataTemplate> </HierarchicalDataTemplate>
<DataTemplate DataType="{x:Type local:LayerPropertyViewModel}"> </ItemsControl.ItemTemplate>
<ContentControl s:View.Model="{Binding TreePropertyViewModel, IsAsync=True}" dd:DragDrop.DragSourceIgnore="True" /> </ItemsControl>
</DataTemplate>
</TreeView.Resources>
</TreeView>
</UserControl> </UserControl>

View File

@ -1,7 +1,10 @@
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Forms;
using System.Windows.Input; using System.Windows.Input;
using Stylet; using Stylet;
using Control = System.Windows.Controls.Control;
using KeyEventArgs = System.Windows.Input.KeyEventArgs;
using Screen = Stylet.Screen;
namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.Tree namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.Tree
{ {

View File

@ -26,8 +26,8 @@
<ListBoxItem ToolTip="Pan over different parts of the surface"> <ListBoxItem ToolTip="Pan over different parts of the surface">
<materialDesign:PackIcon Kind="HandLeft" /> <materialDesign:PackIcon Kind="HandLeft" />
</ListBoxItem> </ListBoxItem>
<ListBoxItem ToolTip="Edit shape in layer (hold SHIFT for incremental changes and X/Y snapping)" IsEnabled="{Binding CanSelectEditTool}"> <ListBoxItem ToolTip="Transform layer shape (hold SHIFT for incremental changes and X/Y snapping)" IsEnabled="{Binding CanSelectEditTool}">
<materialDesign:PackIcon Kind="Edit" /> <materialDesign:PackIcon Kind="TransitConnectionVariant" />
</ListBoxItem> </ListBoxItem>
<ListBoxItem ToolTip="Change layer selection (hold SHIFT to add to existing selection)"> <ListBoxItem ToolTip="Change layer selection (hold SHIFT to add to existing selection)">
<materialDesign:PackIcon Kind="SelectionDrag" /> <materialDesign:PackIcon Kind="SelectionDrag" />