Layer properties - Restored much functionality on the reworked VMs

This commit is contained in:
SpoinkyNL committed 2020-05-24 22:05:04 +02:00
1 parent ea66dcd39e
commit 221c8bc7e7
29 files changed
+440 -209

No files matched your search

@@ -43,6 +43,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties
set => ProfileEditorService.CurrentTime = TimeSpan.FromSeconds(value.Left / ProfileEditorService.PixelsPerSecond);
}
public Layer SelectedLayer { get; set; }
public BindableCollection<LayerPropertyGroupViewModel> LayerPropertyGroups { get; set; }
public TreeViewModel TreeViewModel { get; set; }
public TimelineViewModel TimelineViewModel { get; set; }
@@ -86,9 +87,21 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties
private void PopulateProperties(ProfileElement profileElement)
{
if (SelectedLayer != null)
{
SelectedLayer.LayerBrushUpdated -= SelectedLayerOnLayerBrushUpdated;
SelectedLayer = null;
}
foreach (var layerPropertyGroupViewModel in LayerPropertyGroups)
layerPropertyGroupViewModel.Dispose();
LayerPropertyGroups.Clear();
if (profileElement is Layer layer)
{
SelectedLayer = layer;
SelectedLayer.LayerBrushUpdated += SelectedLayerOnLayerBrushUpdated;
// Add the built-in root groups of the layer
var generalAttribute = Attribute.GetCustomAttribute(
layer.GetType().GetProperty(nameof(layer.General)),
@@ -113,11 +126,35 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties
LayerPropertyGroups.Add(new LayerPropertyGroupViewModel(ProfileEditorService, layer.LayerBrush.BaseProperties, brushDescription));
}
}
else
SelectedLayer = null;
TreeViewModel = new TreeViewModel(this, LayerPropertyGroups);
TimelineViewModel = new TimelineViewModel(this, LayerPropertyGroups);
}
private void SelectedLayerOnLayerBrushUpdated(object sender, EventArgs e)
{
// Get rid of the old layer properties group
if (LayerPropertyGroups.Count == 3)
{
LayerPropertyGroups[2].Dispose();
LayerPropertyGroups.RemoveAt(2);
}
if (SelectedLayer.LayerBrush != null)
{
// Add the rout 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
};
LayerPropertyGroups.Add(new LayerPropertyGroupViewModel(ProfileEditorService, SelectedLayer.LayerBrush.BaseProperties, brushDescription));
}
}
#endregion
#region Controls
@@ -50,6 +50,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties
public override void Dispose()
{
TreePropertyViewModel.Dispose();
TimelinePropertyViewModel.Dispose();
}
public void SetCurrentValue(T value, bool saveChanges)
@@ -18,7 +18,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
EasingFunction = easingFunction;
Description = easingFunction.Humanize();
CreateGeometry();
CreateEasingPoints();
}
public Easings.Functions EasingFunction { get; }
@@ -36,7 +36,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
}
}
private void CreateGeometry()
private void CreateEasingPoints()
{
EasingPoints = new PointCollection();
for (var i = 1; i <= 10; i++)
@@ -45,7 +45,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
#endregion
}
public abstract class TimelineKeyframeViewModel
public abstract class TimelineKeyframeViewModel : PropertyChangedBase
{
private readonly IProfileEditorService _profileEditorService;
private readonly TimelineViewModel _timelineViewModel;
@@ -56,6 +56,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
_profileEditorService = profileEditorService;
_timelineViewModel = timelineViewModel;
BaseLayerPropertyKeyframe = baseLayerPropertyKeyframe;
EasingViewModels = new BindableCollection<TimelineEasingViewModel>();
}
public BaseLayerPropertyKeyframe BaseLayerPropertyKeyframe { get; }
@@ -139,6 +140,16 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
#region Easing
public void ContextMenuOpening()
{
CreateEasingViewModels();
}
public void ContextMenuClosing()
{
EasingViewModels.Clear();
}
private void CreateEasingViewModels()
{
EasingViewModels.AddRange(Enum.GetValues(typeof(Easings.Functions)).Cast<Easings.Functions>().Select(v => new TimelineEasingViewModel(this, v)));
@@ -12,72 +12,82 @@
d:DataContext="{d:DesignInstance local:TimelinePropertyGroupViewModel}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="25" />
<RowDefinition Height="24" />
<RowDefinition Height="1" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Border Height="25" BorderThickness="0,0,0,1" BorderBrush="{DynamicResource MaterialDesignDivider}" Grid.Row="0">
<ItemsControl ItemsSource="{Binding TimelineKeyframeViewModels}"
<ItemsControl Grid.Row="0"
Height="24"
Visibility="{Binding LayerPropertyGroupViewModel.IsExpanded, Converter={x:Static s:BoolToVisibilityConverter.InverseInstance}, Mode=OneWay}"
ItemsSource="{Binding TimelineKeyframeViewModels}"
Background="{DynamicResource MaterialDesignToolBarBackground}"
HorizontalAlignment="Left">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style TargetType="{x:Type ContentPresenter}">
<Setter Property="Canvas.Left" Value="{Binding X}" />
</Style>
</ItemsControl.ItemContainerStyle>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Ellipse Fill="{StaticResource PrimaryHueMidBrush}"
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style TargetType="{x:Type ContentPresenter}">
<Setter Property="Canvas.Left" Value="{Binding X}" />
</Style>
</ItemsControl.ItemContainerStyle>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Ellipse Fill="{StaticResource PrimaryHueMidBrush}"
Stroke="White"
StrokeThickness="0"
Width="10"
Height="10"
Margin="-5,6,0,0"
s:View.ActionTarget="{Binding}">
<Ellipse.Style>
<Style TargetType="{x:Type Ellipse}">
<Style.Triggers>
<DataTrigger Binding="{Binding IsSelected}" Value="True">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="StrokeThickness" To="1" Duration="0:0:0.25" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="StrokeThickness" To="0" Duration="0:0:0.25" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.ExitActions>
</DataTrigger>
</Style.Triggers>
</Style>
</Ellipse.Style>
</Ellipse>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Border>
<ItemsControl ItemsSource="{Binding LayerPropertyGroupViewModel.Children}" Grid.Row="1">
<Ellipse.Style>
<Style TargetType="{x:Type Ellipse}">
<Style.Triggers>
<DataTrigger Binding="{Binding IsSelected}" Value="True">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="StrokeThickness"
To="1" Duration="0:0:0.25" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="StrokeThickness"
To="0" Duration="0:0:0.25" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.ExitActions>
</DataTrigger>
</Style.Triggers>
</Style>
</Ellipse.Style>
</Ellipse>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<Rectangle Grid.Row="1" HorizontalAlignment="Stretch" Fill="{DynamicResource MaterialDesignDivider}" Height="1" />
<ItemsControl Grid.Row="2"
Visibility="{Binding LayerPropertyGroupViewModel.IsExpanded, Converter={x:Static s:BoolToVisibilityConverter.Instance}, Mode=OneWay}"
ItemsSource="{Binding LayerPropertyGroupViewModel.Children}">
<ItemsControl.Resources>
<DataTemplate DataType="{x:Type layerProperties:LayerPropertyGroupViewModel}">
<ContentControl s:View.Model="{Binding TimelinePropertyGroupViewModel}"
VerticalContentAlignment="Stretch"
HorizontalContentAlignment="Stretch"
IsTabStop="False" />
VerticalContentAlignment="Stretch"
HorizontalContentAlignment="Stretch"
IsTabStop="False" />
</DataTemplate>
<DataTemplate DataType="{x:Type layerProperties:LayerPropertyViewModel}">
<ContentControl s:View.Model="{Binding TimelinePropertyBaseViewModel}"
VerticalContentAlignment="Stretch"
HorizontalContentAlignment="Stretch"
IsTabStop="False" />
VerticalContentAlignment="Stretch"
HorizontalContentAlignment="Stretch"
IsTabStop="False" />
</DataTemplate>
</ItemsControl.Resources>
</ItemsControl>
@@ -1,12 +1,12 @@
<UserControl x:Class="Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline.TimelinePropertyView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:s="https://github.com/canton7/Stylet"
mc:Ignorable="d"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
d:DataContext="{d:DesignInstance local:TimelinePropertyViewModel}">
<Border Height="25" BorderThickness="0,0,0,1" BorderBrush="{DynamicResource MaterialDesignDivider}">
@@ -35,7 +35,9 @@
s:View.ActionTarget="{Binding}"
MouseDown="{s:Action KeyframeMouseDown}"
MouseUp="{s:Action KeyframeMouseUp}"
MouseMove="{s:Action KeyframeMouseMove}">
MouseMove="{s:Action KeyframeMouseMove}"
ContextMenuOpening="{s:Action ContextMenuOpening}"
ContextMenuClosing="{s:Action ContextMenuClosing}">
<Ellipse.Style>
<Style TargetType="{x:Type Ellipse}">
<Style.Triggers>
@@ -72,6 +74,9 @@
</MenuItem>
<Separator />
<MenuItem Header="Easing" ItemsSource="{Binding EasingViewModels}">
<MenuItem.Icon>
<materialDesign:PackIcon Kind="Creation" />
</MenuItem.Icon>
<MenuItem.ItemContainerStyle>
<Style TargetType="{x:Type MenuItem}" BasedOn="{StaticResource MaterialDesignMenuItem}">
<Setter Property="IsCheckable" Value="True" />
@@ -105,4 +110,4 @@
</ItemsControl.ItemTemplate>
</ItemsControl>
</Border>
</UserControl>
</UserControl>
@@ -1,4 +1,6 @@
using System.Linq;
using System;
using System.Linq;
using Artemis.UI.Exceptions;
using Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Abstract;
using Artemis.UI.Services.Interfaces;
using Stylet;
@@ -13,27 +15,53 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
{
_profileEditorService = profileEditorService;
LayerPropertyViewModel = (LayerPropertyViewModel<T>) layerPropertyBaseViewModel;
LayerPropertyViewModel.LayerProperty.KeyframeAdded += LayerPropertyOnKeyframeModified;
LayerPropertyViewModel.LayerProperty.KeyframeRemoved += LayerPropertyOnKeyframeModified;
LayerPropertyViewModel.LayerProperty.KeyframesToggled += LayerPropertyOnKeyframeModified;
}
private void LayerPropertyOnKeyframeModified(object sender, EventArgs e)
{
UpdateKeyframes();
}
public LayerPropertyViewModel<T> LayerPropertyViewModel { get; }
public override void UpdateKeyframes(TimelineViewModel timelineViewModel)
public override void UpdateKeyframes()
{
var keyframes = LayerPropertyViewModel.LayerProperty.Keyframes.ToList();
TimelineKeyframeViewModels.RemoveRange(
TimelineKeyframeViewModels.Where(t => !keyframes.Contains(t.BaseLayerPropertyKeyframe))
);
TimelineKeyframeViewModels.AddRange(
keyframes.Where(k => TimelineKeyframeViewModels.All(t => t.BaseLayerPropertyKeyframe != k))
.Select(k => new TimelineKeyframeViewModel<T>(_profileEditorService, timelineViewModel, k))
);
if (TimelineViewModel == null)
throw new ArtemisUIException("Timeline view model must be set before keyframes can be updated");
// Only show keyframes if they are enabled
if (LayerPropertyViewModel.LayerProperty.KeyframesEnabled)
{
var keyframes = LayerPropertyViewModel.LayerProperty.Keyframes.ToList();
var toRemove = TimelineKeyframeViewModels.Where(t => !keyframes.Contains(t.BaseLayerPropertyKeyframe)).ToList();
TimelineKeyframeViewModels.RemoveRange(toRemove);
TimelineKeyframeViewModels.AddRange(
keyframes.Where(k => TimelineKeyframeViewModels.All(t => t.BaseLayerPropertyKeyframe != k))
.Select(k => new TimelineKeyframeViewModel<T>(_profileEditorService, TimelineViewModel, k))
);
}
else
{
TimelineKeyframeViewModels.Clear();
}
foreach (var timelineKeyframeViewModel in TimelineKeyframeViewModels)
timelineKeyframeViewModel.Update(_profileEditorService.PixelsPerSecond);
}
public override void Dispose()
{
LayerPropertyViewModel.LayerProperty.KeyframeAdded -= LayerPropertyOnKeyframeModified;
LayerPropertyViewModel.LayerProperty.KeyframeRemoved -= LayerPropertyOnKeyframeModified;
LayerPropertyViewModel.LayerProperty.KeyframesToggled -= LayerPropertyOnKeyframeModified;
}
}
public abstract class TimelinePropertyViewModel
public abstract class TimelinePropertyViewModel : IDisposable
{
protected TimelinePropertyViewModel(LayerPropertyBaseViewModel layerPropertyBaseViewModel)
{
@@ -42,8 +70,11 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
}
public LayerPropertyBaseViewModel LayerPropertyBaseViewModel { get; }
public TimelineViewModel TimelineViewModel { get; set; }
public BindableCollection<TimelineKeyframeViewModel> TimelineKeyframeViewModels { get; set; }
public abstract void UpdateKeyframes(TimelineViewModel timelineViewModel);
public abstract void UpdateKeyframes();
public abstract void Dispose();
}
}
@@ -1,18 +1,18 @@
<UserControl x:Class="Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline.TimelineView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline"
xmlns:s="https://github.com/canton7/Stylet"
xmlns:s="https://github.com/canton7/Stylet"
mc:Ignorable="d"
d:DesignHeight="25"
d:DesignWidth="800"
d:DataContext="{d:DesignInstance local:TimelineViewModel}">
<Grid Background="{DynamicResource MaterialDesignToolBarBackground}"
MouseDown="{s:Action TimelineCanvasMouseDown}"
MouseUp="{s:Action TimelineCanvasMouseUp}"
MouseMove="{s:Action TimelineCanvasMouseMove}">
MouseDown="{s:Action TimelineCanvasMouseDown}"
MouseUp="{s:Action TimelineCanvasMouseUp}"
MouseMove="{s:Action TimelineCanvasMouseMove}">
<Grid.Triggers>
<EventTrigger RoutedEvent="UIElement.MouseLeftButtonDown">
<BeginStoryboard>
@@ -42,10 +42,11 @@
</ItemsControl>
<!-- Multi-selection rectangle -->
<Path Data="{Binding SelectionRectangle}" Opacity="0"
<Path x:Name="MultiSelectionPath"
Data="{Binding SelectionRectangle}"
Opacity="0"
Stroke="{DynamicResource PrimaryHueLightBrush}"
StrokeThickness="1"
x:Name="MultiSelectionPath"
IsHitTestVisible="False">
<Path.Fill>
<SolidColorBrush Color="{DynamicResource Primary400}" Opacity="0.25" />
@@ -35,7 +35,10 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
foreach (var layerPropertyBaseViewModel in layerPropertyGroupViewModel.GetAllChildren())
{
if (layerPropertyBaseViewModel is LayerPropertyViewModel layerPropertyViewModel)
layerPropertyViewModel.TimelinePropertyBaseViewModel.UpdateKeyframes(this);
{
layerPropertyViewModel.TimelinePropertyBaseViewModel.TimelineViewModel = this;
layerPropertyViewModel.TimelinePropertyBaseViewModel.UpdateKeyframes();
}
}
}
}
@@ -11,12 +11,14 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Tree.PropertyI
{
LayerPropertyViewModel = layerPropertyViewModel;
LayerPropertyViewModel.LayerProperty.Updated += LayerPropertyOnUpdated;
UpdateInputValue();
}
protected PropertyInputViewModel(LayerPropertyViewModel<T> layerPropertyViewModel, IModelValidator validator) : base(validator)
{
LayerPropertyViewModel = layerPropertyViewModel;
LayerPropertyViewModel.LayerProperty.Updated += LayerPropertyOnUpdated;
UpdateInputValue();
}
public LayerPropertyViewModel<T> LayerPropertyViewModel { get; }
@@ -38,6 +40,10 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Tree.PropertyI
LayerPropertyViewModel.LayerProperty.Updated -= LayerPropertyOnUpdated;
}
protected virtual void OnInputValueApplied()
{
}
protected virtual void OnInputValueChanged()
{
}
@@ -50,7 +56,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Tree.PropertyI
private void UpdateInputValue()
{
// Avoid unnecessary UI updates and validator cycles
if (_inputValue.Equals(LayerPropertyViewModel.LayerProperty.CurrentValue))
if (_inputValue != null && _inputValue.Equals(LayerPropertyViewModel.LayerProperty.CurrentValue) || _inputValue == null && LayerPropertyViewModel.LayerProperty.CurrentValue == null)
return;
// Override the input value
@@ -61,20 +67,24 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Tree.PropertyI
NotifyOfPropertyChange(nameof(InputValue));
// Force the validator to run with the overridden value
Validate();
if (Validator != null)
Validate();
}
private void ApplyInputValue()
{
// Force the validator to run
Validate();
if (Validator != null)
Validate();
// Only apply the input value to the layer property if the validator found no errors
if (!HasErrors)
LayerPropertyViewModel.SetCurrentValue(_inputValue, !InputDragging);
OnInputValueChanged();
OnInputValueApplied();
}
#region Event handlers
public void InputDragStarted(object sender, EventArgs e)
@@ -27,7 +27,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Tree.PropertyI
}
public BindableCollection<ValueDescription> ComboboxValues { get; }
public void UpdateEnumValues()
{
var layerBrushProviders = _pluginService.GetPluginsOfType<LayerBrushProvider>();
@@ -47,7 +47,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Tree.PropertyI
ComboboxValues.Clear();
ComboboxValues.AddRange(enumValues);
}
public override void Dispose()
{
_pluginService.PluginLoaded -= PluginServiceOnPluginLoaded;
@@ -58,5 +58,10 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Tree.PropertyI
{
UpdateEnumValues();
}
protected override void OnInputValueApplied()
{
_layerService.InstantiateLayerBrush(LayerPropertyViewModel.LayerProperty.Layer);
}
}
}
@@ -8,15 +8,17 @@
xmlns:shared="clr-namespace:Artemis.UI.Shared;assembly=Artemis.UI.Shared"
xmlns:controls="clr-namespace:Artemis.UI.Shared.Controls;assembly=Artemis.UI.Shared"
xmlns:propertyInput="clr-namespace:Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Tree.PropertyInput"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
d:DataContext="{d:DesignInstance propertyInput:FloatPropertyInputViewModel}">
<StackPanel Orientation="Horizontal">
<TextBlock Margin="0 0 5 4" Width="10" VerticalAlignment="Bottom" Text="{Binding LayerPropertyViewModel.PropertyDescription.InputPrefix}" />
<controls:DraggableFloat Value="{Binding InputValue}"
StepSize="{Binding LayerPropertyViewModel.PropertyDescription.InputStepSize}"
DragStarted="{s:Action InputDragStarted}"
DragEnded="{s:Action InputDragEnded}" />
materialDesign:ValidationAssist.UsePopup="True"
StepSize="{Binding LayerPropertyViewModel.PropertyDescription.InputStepSize}"
DragStarted="{s:Action InputDragStarted}"
DragEnded="{s:Action InputDragEnded}" />
<TextBlock Margin="5 0 0 4" Width="10" VerticalAlignment="Bottom" Text="{Binding LayerPropertyViewModel.PropertyDescription.InputAffix}" />
</StackPanel>
</UserControl>
@@ -8,12 +8,14 @@
xmlns:shared="clr-namespace:Artemis.UI.Shared;assembly=Artemis.UI.Shared"
xmlns:controls="clr-namespace:Artemis.UI.Shared.Controls;assembly=Artemis.UI.Shared"
xmlns:propertyInput="clr-namespace:Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Tree.PropertyInput"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
d:DataContext="{d:DesignInstance propertyInput:IntPropertyInputViewModel}">
<StackPanel Orientation="Horizontal">
<TextBlock Margin="0 0 5 4" Width="10" VerticalAlignment="Bottom" Text="{Binding LayerPropertyViewModel.PropertyDescription.InputPrefix}" />
<controls:DraggableFloat Value="{Binding InputValue}"
materialDesign:ValidationAssist.UsePopup="True"
StepSize="{Binding LayerPropertyViewModel.PropertyDescription.InputStepSize}"
DragStarted="{s:Action InputDragStarted}"
DragEnded="{s:Action InputDragEnded}" />
@@ -7,7 +7,8 @@
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:s="https://github.com/canton7/Stylet"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
d:DesignHeight="450" d:DesignWidth="800"
d:DataContext="{d:DesignInstance {x:Type local:TreePropertyViewModel}}">
<Grid Height="22">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
@@ -20,7 +21,7 @@
ToolTip="Toggle key-framing"
Width="18"
Height="18"
IsChecked="{Binding LayerPropertyViewModel.LayerProperty.KeyframesEnabled}"
IsChecked="{Binding KeyframesEnabled}"
IsEnabled="{Binding LayerPropertyViewModel.LayerProperty.KeyframesSupported}"
VerticalAlignment="Center" Padding="-25">
<materialDesign:PackIcon Kind="Stopwatch" Height="13" Width="13" />
@@ -1,4 +1,7 @@
using System;
using System.Linq;
using Artemis.Core.Models.Profile.LayerProperties;
using Artemis.Core.Utilities;
using Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Abstract;
using Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Tree.PropertyInput.Abstract;
using Artemis.UI.Services.Interfaces;
@@ -20,10 +23,37 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Tree
public LayerPropertyViewModel<T> LayerPropertyViewModel { get; }
public PropertyInputViewModel<T> PropertyInputViewModel { get; set; }
public bool KeyframesEnabled
{
get => LayerPropertyViewModel.LayerProperty.KeyframesEnabled;
set => ApplyKeyframesEnabled(value);
}
public override void Dispose()
{
PropertyInputViewModel.Dispose();
}
private void ApplyKeyframesEnabled(bool enable)
{
// If enabling keyframes for the first time, add a keyframe with the current value at the current position
if (enable && !LayerPropertyViewModel.LayerProperty.Keyframes.Any())
{
LayerPropertyViewModel.LayerProperty.AddKeyframe(new LayerPropertyKeyframe<T>(
LayerPropertyViewModel.LayerProperty.CurrentValue,
_profileEditorService.CurrentTime,
Easings.Functions.Linear,
LayerPropertyViewModel.LayerProperty
));
}
// If disabling keyframes, set the base value to the current value
else if (!enable && LayerPropertyViewModel.LayerProperty.Keyframes.Any())
LayerPropertyViewModel.LayerProperty.BaseValue = LayerPropertyViewModel.LayerProperty.CurrentValue;
LayerPropertyViewModel.LayerProperty.KeyframesEnabled = enable;
_profileEditorService.UpdateSelectedProfileElement();
}
}
public abstract class TreePropertyViewModel : IDisposable
@@ -35,8 +35,7 @@
BorderThickness="0,0,0,1"
Height="25"
Padding="{TemplateBinding Padding}">
<Grid
Margin="{Binding Converter={StaticResource lengthConverter}, RelativeSource={RelativeSource TemplatedParent}}">
<Grid Margin="{Binding Converter={StaticResource lengthConverter}, RelativeSource={RelativeSource TemplatedParent}}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="19" />
<ColumnDefinition />
@@ -94,8 +93,7 @@
</Style>
</TreeView.ItemContainerStyle>
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type layerProperties:LayerPropertyGroupViewModel}"
ItemsSource="{Binding Children}">
<HierarchicalDataTemplate DataType="{x:Type layerProperties:LayerPropertyGroupViewModel}" ItemsSource="{Binding Children}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding PropertyGroupDescription.Name}"
ToolTip="{Binding PropertyGroupDescription.Description}" Margin="5 0"
@@ -1,4 +1,5 @@
using System.Windows;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using Stylet;
@@ -19,7 +20,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Tree
public void PropertyTreePreviewMouseWheel(object sender, MouseWheelEventArgs e)
{
if (e.Handled || !(sender is TreeView))
if (e.Handled || !(sender is System.Windows.Controls.TreeView))
return;
e.Handled = true;
@@ -103,19 +103,23 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization
OpacityGeometry = opacityGeometry;
// Render the store as a bitmap
var drawingImage = new DrawingImage(new GeometryDrawing(new SolidColorBrush(Colors.Black), null, LayerGeometry));
var image = new Image {Source = drawingImage};
var bitmap = new RenderTargetBitmap(
(int) (LayerGeometry.Bounds.Width * 2.5),
(int) (LayerGeometry.Bounds.Height * 2.5),
96,
96,
PixelFormats.Pbgra32
);
image.Arrange(new Rect(0, 0, bitmap.Width, bitmap.Height));
bitmap.Render(image);
bitmap.Freeze();
LayerGeometryBitmap = bitmap;
Execute.OnUIThread(() =>
{
var drawingImage = new DrawingImage(new GeometryDrawing(new SolidColorBrush(Colors.Black), null, LayerGeometry));
var image = new Image { Source = drawingImage };
var bitmap = new RenderTargetBitmap(
(int)(LayerGeometry.Bounds.Width * 2.5),
(int)(LayerGeometry.Bounds.Height * 2.5),
96,
96,
PixelFormats.Pbgra32
);
image.Arrange(new Rect(0, 0, bitmap.Width, bitmap.Height));
bitmap.Render(image);
bitmap.Freeze();
LayerGeometryBitmap = bitmap;
});
}
private void CreateShapeGeometry()