mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-13 05:48:35 +00:00
Profiles - Made data bindings compatible with timeline changes
This commit is contained in:
parent
997ab005d8
commit
0f5c2b80c4
@ -293,6 +293,10 @@ namespace Artemis.Core
|
|||||||
if (Operator == null || LeftPath == null || !LeftPath.IsValid)
|
if (Operator == null || LeftPath == null || !LeftPath.IsValid)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// If the operator does not support a right side, immediately evaluate with null
|
||||||
|
if (Operator.RightSideType == null)
|
||||||
|
return Operator.InternalEvaluate(LeftPath.GetValue(), null);
|
||||||
|
|
||||||
// Compare with a static value
|
// Compare with a static value
|
||||||
if (PredicateType == ProfileRightSideType.Static)
|
if (PredicateType == ProfileRightSideType.Static)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -55,11 +55,14 @@ namespace Artemis.Core
|
|||||||
|
|
||||||
private object? GetEventPathValue(DataModelPath path, object target)
|
private object? GetEventPathValue(DataModelPath path, object target)
|
||||||
{
|
{
|
||||||
if (!(path.Target is EventPredicateWrapperDataModel wrapper))
|
lock (path)
|
||||||
throw new ArtemisCoreException("Data model condition event predicate has a path with an invalid target");
|
{
|
||||||
|
if (!(path.Target is EventPredicateWrapperDataModel wrapper))
|
||||||
|
throw new ArtemisCoreException("Data model condition event predicate has a path with an invalid target");
|
||||||
|
|
||||||
wrapper.UntypedArguments = target;
|
wrapper.UntypedArguments = target;
|
||||||
return path.GetValue();
|
return path.GetValue();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Initialization
|
#region Initialization
|
||||||
@ -124,6 +127,10 @@ namespace Artemis.Core
|
|||||||
if (Operator == null || LeftPath == null || !LeftPath.IsValid)
|
if (Operator == null || LeftPath == null || !LeftPath.IsValid)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// If the operator does not support a right side, immediately evaluate with null
|
||||||
|
if (Operator.RightSideType == null)
|
||||||
|
return Operator.InternalEvaluate(GetEventPathValue(LeftPath, target), null);
|
||||||
|
|
||||||
// Compare with a static value
|
// Compare with a static value
|
||||||
if (PredicateType == ProfileRightSideType.Static)
|
if (PredicateType == ProfileRightSideType.Static)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -139,16 +139,24 @@ namespace Artemis.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="timeline">The timeline to apply during update</param>
|
/// <param name="timeline">The timeline to apply during update</param>
|
||||||
public void Update(Timeline timeline)
|
public void Update(Timeline timeline)
|
||||||
|
{
|
||||||
|
UpdateWithDelta(timeline.Delta);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Updates the smoothing progress of the data binding
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="delta">The delta to apply during update</param>
|
||||||
|
public void UpdateWithDelta(TimeSpan delta)
|
||||||
{
|
{
|
||||||
if (_disposed)
|
if (_disposed)
|
||||||
throw new ObjectDisposedException("DataBinding");
|
throw new ObjectDisposedException("DataBinding");
|
||||||
|
|
||||||
// Data bindings cannot go back in time like brushes
|
// Data bindings cannot go back in time like brushes
|
||||||
TimeSpan deltaTime = timeline.Delta;
|
if (delta < TimeSpan.Zero)
|
||||||
if (deltaTime < TimeSpan.Zero)
|
delta = TimeSpan.Zero;
|
||||||
deltaTime = TimeSpan.Zero;
|
|
||||||
|
|
||||||
_easingProgress = _easingProgress.Add(deltaTime);
|
_easingProgress = _easingProgress.Add(delta);
|
||||||
if (_easingProgress > EasingTime)
|
if (_easingProgress > EasingTime)
|
||||||
_easingProgress = EasingTime;
|
_easingProgress = EasingTime;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -42,10 +42,8 @@ namespace Artemis.Core
|
|||||||
|
|
||||||
CurrentValue = BaseValue;
|
CurrentValue = BaseValue;
|
||||||
|
|
||||||
if (ProfileElement.ApplyKeyframesEnabled)
|
UpdateKeyframes(timeline);
|
||||||
UpdateKeyframes(timeline);
|
UpdateDataBindings(timeline);
|
||||||
if (ProfileElement.ApplyDataBindingsEnabled)
|
|
||||||
UpdateDataBindings(timeline);
|
|
||||||
|
|
||||||
OnUpdated();
|
OnUpdated();
|
||||||
}
|
}
|
||||||
@ -421,6 +419,10 @@ namespace Artemis.Core
|
|||||||
|
|
||||||
private void UpdateDataBindings(Timeline timeline)
|
private void UpdateDataBindings(Timeline timeline)
|
||||||
{
|
{
|
||||||
|
// To avoid data bindings applying at non-regular updating (during editing) only update when not overriden
|
||||||
|
if (timeline.IsOverridden)
|
||||||
|
return;
|
||||||
|
|
||||||
foreach (IDataBinding dataBinding in _dataBindings)
|
foreach (IDataBinding dataBinding in _dataBindings)
|
||||||
{
|
{
|
||||||
dataBinding.Update(timeline);
|
dataBinding.Update(timeline);
|
||||||
|
|||||||
@ -15,8 +15,6 @@ namespace Artemis.Core
|
|||||||
{
|
{
|
||||||
protected RenderProfileElement()
|
protected RenderProfileElement()
|
||||||
{
|
{
|
||||||
ApplyDataBindingsEnabled = true;
|
|
||||||
ApplyKeyframesEnabled = true;
|
|
||||||
Timeline = new Timeline();
|
Timeline = new Timeline();
|
||||||
|
|
||||||
LayerEffectStore.LayerEffectAdded += LayerEffectStoreOnLayerEffectAdded;
|
LayerEffectStore.LayerEffectAdded += LayerEffectStoreOnLayerEffectAdded;
|
||||||
@ -300,16 +298,6 @@ namespace Artemis.Core
|
|||||||
set => SetAndNotify(ref _displayCondition, value);
|
set => SetAndNotify(ref _displayCondition, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets whether keyframes should be applied when this profile element updates
|
|
||||||
/// </summary>
|
|
||||||
public bool ApplyKeyframesEnabled { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets whether data bindings should be applied when this profile element updates
|
|
||||||
/// </summary>
|
|
||||||
public bool ApplyDataBindingsEnabled { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Evaluates the display conditions on this element and applies any required changes to the <see cref="Timeline"/>
|
/// Evaluates the display conditions on this element and applies any required changes to the <see cref="Timeline"/>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@ -137,6 +137,11 @@ namespace Artemis.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public bool IsFinished => Position > Length || Length == TimeSpan.Zero;
|
public bool IsFinished => Position > Length || Length == TimeSpan.Zero;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a boolean indicating whether the timeline progress has been overridden
|
||||||
|
/// </summary>
|
||||||
|
public bool IsOverridden { get; private set; }
|
||||||
|
|
||||||
#region Segments
|
#region Segments
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -293,6 +298,7 @@ namespace Artemis.Core
|
|||||||
{
|
{
|
||||||
Delta += delta;
|
Delta += delta;
|
||||||
Position += delta;
|
Position += delta;
|
||||||
|
IsOverridden = false;
|
||||||
|
|
||||||
if (stickToMainSegment && Position >= MainSegmentStartPosition)
|
if (stickToMainSegment && Position >= MainSegmentStartPosition)
|
||||||
{
|
{
|
||||||
@ -371,6 +377,8 @@ namespace Artemis.Core
|
|||||||
{
|
{
|
||||||
Delta += position - Position;
|
Delta += position - Position;
|
||||||
Position = position;
|
Position = position;
|
||||||
|
IsOverridden = true;
|
||||||
|
|
||||||
if (stickToMainSegment && Position >= MainSegmentStartPosition)
|
if (stickToMainSegment && Position >= MainSegmentStartPosition)
|
||||||
Position = MainSegmentStartPosition + TimeSpan.FromMilliseconds(Position.TotalMilliseconds % MainSegmentLength.TotalMilliseconds);
|
Position = MainSegmentStartPosition + TimeSpan.FromMilliseconds(Position.TotalMilliseconds % MainSegmentLength.TotalMilliseconds);
|
||||||
|
|
||||||
|
|||||||
@ -43,7 +43,7 @@ namespace Artemis.Core
|
|||||||
/// The action to call every time the interval has passed. The delta time parameter represents the
|
/// The action to call every time the interval has passed. The delta time parameter represents the
|
||||||
/// time passed since the last update in seconds
|
/// time passed since the last update in seconds
|
||||||
/// </param>
|
/// </param>
|
||||||
/// <returns>The resulting plugin update registration</returns>
|
/// <returns>The resulting plugin update registration which can be used to stop the update</returns>
|
||||||
public PluginUpdateRegistration AddTimedUpdate(TimeSpan interval, Action<double> action)
|
public PluginUpdateRegistration AddTimedUpdate(TimeSpan interval, Action<double> action)
|
||||||
{
|
{
|
||||||
if (action == null)
|
if (action == null)
|
||||||
|
|||||||
@ -16,12 +16,21 @@
|
|||||||
<ResourceDictionary Source="pack://application:,,,/Artemis.UI.Shared;component/ResourceDictionaries/DataModelConditions.xaml" />
|
<ResourceDictionary Source="pack://application:,,,/Artemis.UI.Shared;component/ResourceDictionaries/DataModelConditions.xaml" />
|
||||||
<ResourceDictionary>
|
<ResourceDictionary>
|
||||||
<shared:NullToVisibilityConverter x:Key="NullToVisibilityConverter" />
|
<shared:NullToVisibilityConverter x:Key="NullToVisibilityConverter" />
|
||||||
|
<Style x:Key="DataModelConditionButtonCornerToggle" BasedOn="{StaticResource DataModelConditionButton}" TargetType="Button">
|
||||||
|
<Style.Triggers>
|
||||||
|
<DataTrigger Binding="{Binding DisplaySwitchButton}" Value="True">
|
||||||
|
<Setter Property="materialDesign:ButtonAssist.CornerRadius" Value="0 2 2 0" />
|
||||||
|
</DataTrigger>
|
||||||
|
<DataTrigger Binding="{Binding DisplaySwitchButton}" Value="False">
|
||||||
|
<Setter Property="materialDesign:ButtonAssist.CornerRadius" Value="2" />
|
||||||
|
</DataTrigger>
|
||||||
|
</Style.Triggers>
|
||||||
|
</Style>
|
||||||
</ResourceDictionary>
|
</ResourceDictionary>
|
||||||
</ResourceDictionary.MergedDictionaries>
|
</ResourceDictionary.MergedDictionaries>
|
||||||
</ResourceDictionary>
|
</ResourceDictionary>
|
||||||
</UserControl.Resources>
|
</UserControl.Resources>
|
||||||
|
<Grid>
|
||||||
<Grid Margin="3 -4">
|
|
||||||
<StackPanel Orientation="Horizontal" Visibility="{Binding InputViewModel, Converter={StaticResource NullToVisibilityConverter}, ConverterParameter=Inverted}">
|
<StackPanel Orientation="Horizontal" Visibility="{Binding InputViewModel, Converter={StaticResource NullToVisibilityConverter}, ConverterParameter=Inverted}">
|
||||||
<Button Style="{StaticResource MaterialDesignFlatDarkBgButton}"
|
<Button Style="{StaticResource MaterialDesignFlatDarkBgButton}"
|
||||||
Background="{Binding SwitchButtonBrush}"
|
Background="{Binding SwitchButtonBrush}"
|
||||||
@ -31,15 +40,14 @@
|
|||||||
Width="22"
|
Width="22"
|
||||||
FontSize="12"
|
FontSize="12"
|
||||||
materialDesign:ButtonAssist.CornerRadius="2 0 0 2"
|
materialDesign:ButtonAssist.CornerRadius="2 0 0 2"
|
||||||
Margin="0 0 -3 0"
|
Margin="3 0 -3 0"
|
||||||
HorizontalAlignment="Left"
|
HorizontalAlignment="Left"
|
||||||
ToolTip="Switch to data model value"
|
ToolTip="Switch to data model value"
|
||||||
Command="{s:Action SwitchToDynamic}"
|
Command="{s:Action SwitchToDynamic}"
|
||||||
Visibility="{Binding DisplaySwitchButton, Converter={x:Static s:BoolToVisibilityConverter.Instance}, Mode=OneWay}">
|
Visibility="{Binding DisplaySwitchButton, Converter={x:Static s:BoolToVisibilityConverter.Instance}, Mode=OneWay}">
|
||||||
<materialDesign:PackIcon Kind="SwapHorizontal" />
|
<materialDesign:PackIcon Kind="SwapHorizontal" />
|
||||||
</Button>
|
</Button>
|
||||||
<Button Style="{StaticResource DataModelConditionButton}"
|
<Button Style="{StaticResource DataModelConditionButtonCornerToggle}"
|
||||||
materialDesign:ButtonAssist.CornerRadius="0 2 2 0"
|
|
||||||
Background="{Binding ButtonBrush}"
|
Background="{Binding ButtonBrush}"
|
||||||
BorderBrush="{Binding ButtonBrush}"
|
BorderBrush="{Binding ButtonBrush}"
|
||||||
Command="{s:Action ActivateInputViewModel}"
|
Command="{s:Action ActivateInputViewModel}"
|
||||||
|
|||||||
@ -15,7 +15,7 @@
|
|||||||
</ResourceDictionary.MergedDictionaries>
|
</ResourceDictionary.MergedDictionaries>
|
||||||
</ResourceDictionary>
|
</ResourceDictionary>
|
||||||
</UserControl.Resources>
|
</UserControl.Resources>
|
||||||
<Grid Margin="0 3">
|
<Grid>
|
||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
<RowDefinition Height="Auto" />
|
<RowDefinition Height="Auto" />
|
||||||
<RowDefinition Height="*" />
|
<RowDefinition Height="*" />
|
||||||
@ -52,7 +52,7 @@
|
|||||||
triggered
|
triggered
|
||||||
</TextBlock>
|
</TextBlock>
|
||||||
|
|
||||||
<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 3 0 0">
|
||||||
<ItemsControl.ItemTemplate>
|
<ItemsControl.ItemTemplate>
|
||||||
<DataTemplate>
|
<DataTemplate>
|
||||||
<ContentControl s:View.Model="{Binding}" VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch" IsTabStop="False" />
|
<ContentControl s:View.Model="{Binding}" VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch" IsTabStop="False" />
|
||||||
|
|||||||
@ -133,7 +133,7 @@
|
|||||||
<materialDesign:PackIcon Kind="Add" Width="18" Height="18" />
|
<materialDesign:PackIcon Kind="Add" Width="18" Height="18" />
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<ItemsControl Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="2" ItemsSource="{Binding Items, IsAsync=True}">
|
<ItemsControl Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="2" ItemsSource="{Binding Items, IsAsync=True}" Margin="0 3 0 0">
|
||||||
<ItemsControl.ItemTemplate>
|
<ItemsControl.ItemTemplate>
|
||||||
<DataTemplate>
|
<DataTemplate>
|
||||||
<ContentControl s:View.Model="{Binding}" VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch" IsTabStop="False" />
|
<ContentControl s:View.Model="{Binding}" VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch" IsTabStop="False" />
|
||||||
|
|||||||
@ -131,7 +131,6 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions
|
|||||||
// Remove VMs of effects no longer applied on the layer
|
// Remove VMs of effects no longer applied on the layer
|
||||||
Items.RemoveRange(Items.Where(c => !DataModelConditionGroup.Children.Contains(c.Model)).ToList());
|
Items.RemoveRange(Items.Where(c => !DataModelConditionGroup.Children.Contains(c.Model)).ToList());
|
||||||
|
|
||||||
List<DataModelConditionViewModel> viewModels = new List<DataModelConditionViewModel>();
|
|
||||||
foreach (DataModelConditionPart childModel in Model.Children)
|
foreach (DataModelConditionPart childModel in Model.Children)
|
||||||
{
|
{
|
||||||
if (Items.Any(c => c.Model == childModel))
|
if (Items.Any(c => c.Model == childModel))
|
||||||
@ -140,32 +139,28 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions
|
|||||||
switch (childModel)
|
switch (childModel)
|
||||||
{
|
{
|
||||||
case DataModelConditionGroup dataModelConditionGroup:
|
case DataModelConditionGroup dataModelConditionGroup:
|
||||||
viewModels.Add(_dataModelConditionsVmFactory.DataModelConditionGroupViewModel(dataModelConditionGroup, GroupType));
|
Items.Add(_dataModelConditionsVmFactory.DataModelConditionGroupViewModel(dataModelConditionGroup, GroupType));
|
||||||
break;
|
break;
|
||||||
case DataModelConditionList dataModelConditionList:
|
case DataModelConditionList dataModelConditionList:
|
||||||
viewModels.Add(_dataModelConditionsVmFactory.DataModelConditionListViewModel(dataModelConditionList));
|
Items.Add(_dataModelConditionsVmFactory.DataModelConditionListViewModel(dataModelConditionList));
|
||||||
break;
|
break;
|
||||||
case DataModelConditionEvent dataModelConditionEvent:
|
case DataModelConditionEvent dataModelConditionEvent:
|
||||||
viewModels.Add(_dataModelConditionsVmFactory.DataModelConditionEventViewModel(dataModelConditionEvent));
|
Items.Add(_dataModelConditionsVmFactory.DataModelConditionEventViewModel(dataModelConditionEvent));
|
||||||
break;
|
break;
|
||||||
case DataModelConditionGeneralPredicate dataModelConditionGeneralPredicate:
|
case DataModelConditionGeneralPredicate dataModelConditionGeneralPredicate:
|
||||||
viewModels.Add(_dataModelConditionsVmFactory.DataModelConditionGeneralPredicateViewModel(dataModelConditionGeneralPredicate));
|
Items.Add(_dataModelConditionsVmFactory.DataModelConditionGeneralPredicateViewModel(dataModelConditionGeneralPredicate));
|
||||||
break;
|
break;
|
||||||
case DataModelConditionListPredicate dataModelConditionListPredicate:
|
case DataModelConditionListPredicate dataModelConditionListPredicate:
|
||||||
viewModels.Add(_dataModelConditionsVmFactory.DataModelConditionListPredicateViewModel(dataModelConditionListPredicate));
|
Items.Add(_dataModelConditionsVmFactory.DataModelConditionListPredicateViewModel(dataModelConditionListPredicate));
|
||||||
break;
|
break;
|
||||||
case DataModelConditionEventPredicate dataModelConditionEventPredicate:
|
case DataModelConditionEventPredicate dataModelConditionEventPredicate:
|
||||||
viewModels.Add(_dataModelConditionsVmFactory.DataModelConditionEventPredicateViewModel(dataModelConditionEventPredicate));
|
Items.Add(_dataModelConditionsVmFactory.DataModelConditionEventPredicateViewModel(dataModelConditionEventPredicate));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (viewModels.Any())
|
|
||||||
Items.AddRange(viewModels);
|
|
||||||
|
|
||||||
// Ensure the items are in the same order as on the model
|
// Ensure the items are in the same order as on the model
|
||||||
((BindableCollection<DataModelConditionViewModel>) Items).Sort(i => Model.Children.IndexOf(i.Model));
|
((BindableCollection<DataModelConditionViewModel>) Items).Sort(i => Model.Children.IndexOf(i.Model));
|
||||||
|
|
||||||
foreach (DataModelConditionViewModel childViewModel in Items)
|
foreach (DataModelConditionViewModel childViewModel in Items)
|
||||||
childViewModel.Update();
|
childViewModel.Update();
|
||||||
|
|
||||||
|
|||||||
@ -16,7 +16,7 @@
|
|||||||
</ResourceDictionary.MergedDictionaries>
|
</ResourceDictionary.MergedDictionaries>
|
||||||
</ResourceDictionary>
|
</ResourceDictionary>
|
||||||
</UserControl.Resources>
|
</UserControl.Resources>
|
||||||
<Grid Margin="0 3">
|
<Grid>
|
||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
<RowDefinition Height="Auto" />
|
<RowDefinition Height="Auto" />
|
||||||
<RowDefinition Height="*" />
|
<RowDefinition Height="*" />
|
||||||
|
|||||||
@ -21,7 +21,7 @@
|
|||||||
</ResourceDictionary.MergedDictionaries>
|
</ResourceDictionary.MergedDictionaries>
|
||||||
</ResourceDictionary>
|
</ResourceDictionary>
|
||||||
</UserControl.Resources>
|
</UserControl.Resources>
|
||||||
<Grid Margin="0 3">
|
<Grid Margin="0 0 0 3">
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="Auto" />
|
<ColumnDefinition Width="Auto" />
|
||||||
<ColumnDefinition Width="Auto" />
|
<ColumnDefinition Width="Auto" />
|
||||||
|
|||||||
@ -21,7 +21,7 @@
|
|||||||
</ResourceDictionary.MergedDictionaries>
|
</ResourceDictionary.MergedDictionaries>
|
||||||
</ResourceDictionary>
|
</ResourceDictionary>
|
||||||
</UserControl.Resources>
|
</UserControl.Resources>
|
||||||
<Grid Margin="0 3">
|
<Grid Margin="0 0 0 3">
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="Auto" />
|
<ColumnDefinition Width="Auto" />
|
||||||
<ColumnDefinition Width="Auto" />
|
<ColumnDefinition Width="Auto" />
|
||||||
|
|||||||
@ -21,7 +21,7 @@
|
|||||||
</ResourceDictionary.MergedDictionaries>
|
</ResourceDictionary.MergedDictionaries>
|
||||||
</ResourceDictionary>
|
</ResourceDictionary>
|
||||||
</UserControl.Resources>
|
</UserControl.Resources>
|
||||||
<Grid Margin="0 3">
|
<Grid Margin="0 0 0 3">
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="Auto" />
|
<ColumnDefinition Width="Auto" />
|
||||||
<ColumnDefinition Width="Auto" />
|
<ColumnDefinition Width="Auto" />
|
||||||
|
|||||||
@ -5,18 +5,13 @@
|
|||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
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:dd="urn:gong-wpf-dragdrop" xmlns:Converters="clr-namespace:Artemis.UI.Converters"
|
xmlns:dd="urn:gong-wpf-dragdrop"
|
||||||
xmlns:utilities="clr-namespace:Artemis.UI.Utilities"
|
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
d:DesignHeight="450" d:DesignWidth="800">
|
d:DesignHeight="450" d:DesignWidth="800">
|
||||||
<UserControl.Resources>
|
<UserControl.Resources>
|
||||||
<ResourceDictionary>
|
<ResourceDictionary>
|
||||||
<ResourceDictionary.MergedDictionaries>
|
<ResourceDictionary.MergedDictionaries>
|
||||||
<ResourceDictionary Source="pack://application:,,,/Artemis.UI;component/ResourceDictionaries/DataModelConditions.xaml" />
|
<ResourceDictionary Source="pack://application:,,,/Artemis.UI;component/ResourceDictionaries/DataModelConditions.xaml" />
|
||||||
<ResourceDictionary>
|
|
||||||
<Converters:NullToVisibilityConverter x:Key="NullToVisibilityConverter" />
|
|
||||||
<utilities:BindingProxy x:Key="DataContextProxy" Data="{Binding}" />
|
|
||||||
</ResourceDictionary>
|
|
||||||
</ResourceDictionary.MergedDictionaries>
|
</ResourceDictionary.MergedDictionaries>
|
||||||
</ResourceDictionary>
|
</ResourceDictionary>
|
||||||
</UserControl.Resources>
|
</UserControl.Resources>
|
||||||
@ -27,43 +22,16 @@
|
|||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
<Button Grid.Row="0"
|
<Button Grid.Row="0"
|
||||||
Style="{StaticResource DataModelConditionButtonLeftClickMenu}"
|
Style="{StaticResource DataModelConditionButton}"
|
||||||
Background="{StaticResource PrimaryHueMidBrush}"
|
Background="{StaticResource PrimaryHueMidBrush}"
|
||||||
BorderBrush="{StaticResource PrimaryHueMidBrush}"
|
BorderBrush="{StaticResource PrimaryHueMidBrush}"
|
||||||
HorizontalAlignment="Right">
|
HorizontalAlignment="Right"
|
||||||
|
Command="{s:Action AddCondition}">
|
||||||
ADD CONDITION
|
ADD CONDITION
|
||||||
<Button.ContextMenu>
|
|
||||||
<ContextMenu>
|
|
||||||
<MenuItem Header="Add static condition"
|
|
||||||
ToolTip="A condition that compares with a static input"
|
|
||||||
Command="{s:Action AddCondition}"
|
|
||||||
CommandParameter="Static">
|
|
||||||
<MenuItem.Icon>
|
|
||||||
<materialDesign:PackIcon Kind="FormTextarea" />
|
|
||||||
</MenuItem.Icon>
|
|
||||||
</MenuItem>
|
|
||||||
<MenuItem Header="Add dynamic condition"
|
|
||||||
ToolTip="A condition that compares with a data model property"
|
|
||||||
Command="{s:Action AddCondition}"
|
|
||||||
CommandParameter="Dynamic">
|
|
||||||
<MenuItem.Icon>
|
|
||||||
<materialDesign:PackIcon Kind="Link" />
|
|
||||||
</MenuItem.Icon>
|
|
||||||
</MenuItem>
|
|
||||||
<MenuItem Header="Add list condition"
|
|
||||||
ToolTip="A condition that evaluates on items in a list"
|
|
||||||
Command="{s:Action AddCondition}"
|
|
||||||
CommandParameter="List">
|
|
||||||
<MenuItem.Icon>
|
|
||||||
<materialDesign:PackIcon Kind="FormatListBulleted" />
|
|
||||||
</MenuItem.Icon>
|
|
||||||
</MenuItem>
|
|
||||||
</ContextMenu>
|
|
||||||
</Button.ContextMenu>
|
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<ListBox Grid.Row="1"
|
<ListBox Grid.Row="1"
|
||||||
ItemsSource="{Binding ConditionViewModels}"
|
ItemsSource="{Binding Items}"
|
||||||
materialDesign:RippleAssist.IsDisabled="True"
|
materialDesign:RippleAssist.IsDisabled="True"
|
||||||
dd:DragDrop.IsDragSource="True"
|
dd:DragDrop.IsDragSource="True"
|
||||||
dd:DragDrop.IsDropTarget="True"
|
dd:DragDrop.IsDropTarget="True"
|
||||||
|
|||||||
@ -10,7 +10,7 @@ using Stylet;
|
|||||||
|
|
||||||
namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings.ConditionalDataBinding
|
namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings.ConditionalDataBinding
|
||||||
{
|
{
|
||||||
public class ConditionalDataBindingModeViewModel<TLayerProperty, TProperty> : Screen, IDataBindingModeViewModel
|
public class ConditionalDataBindingModeViewModel<TLayerProperty, TProperty> : Conductor<DataBindingConditionViewModel<TLayerProperty, TProperty>>.Collection.AllActive, IDataBindingModeViewModel
|
||||||
{
|
{
|
||||||
private readonly IDataBindingsVmFactory _dataBindingsVmFactory;
|
private readonly IDataBindingsVmFactory _dataBindingsVmFactory;
|
||||||
private readonly IProfileEditorService _profileEditorService;
|
private readonly IProfileEditorService _profileEditorService;
|
||||||
@ -24,18 +24,83 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings.Conditio
|
|||||||
_dataBindingsVmFactory = dataBindingsVmFactory;
|
_dataBindingsVmFactory = dataBindingsVmFactory;
|
||||||
|
|
||||||
ConditionalDataBinding = conditionalDataBinding;
|
ConditionalDataBinding = conditionalDataBinding;
|
||||||
ConditionViewModels = new BindableCollection<DataBindingConditionViewModel<TLayerProperty, TProperty>>();
|
|
||||||
|
|
||||||
Initialize();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ConditionalDataBinding<TLayerProperty, TProperty> ConditionalDataBinding { get; }
|
public ConditionalDataBinding<TLayerProperty, TProperty> ConditionalDataBinding { get; }
|
||||||
public BindableCollection<DataBindingConditionViewModel<TLayerProperty, TProperty>> ConditionViewModels { get; }
|
|
||||||
|
public void AddCondition()
|
||||||
|
{
|
||||||
|
DataBindingCondition<TLayerProperty, TProperty> condition = ConditionalDataBinding.AddCondition();
|
||||||
|
|
||||||
|
// Find the VM of the new condition
|
||||||
|
DataBindingConditionViewModel<TLayerProperty, TProperty> viewModel = Items.First(c => c.DataBindingCondition == condition);
|
||||||
|
viewModel.ActiveItem.AddCondition();
|
||||||
|
|
||||||
|
_profileEditorService.UpdateSelectedProfileElement();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnInitialActivate()
|
||||||
|
{
|
||||||
|
base.OnInitialActivate();
|
||||||
|
Initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateItems()
|
||||||
|
{
|
||||||
|
_updating = true;
|
||||||
|
|
||||||
|
// Remove old VMs
|
||||||
|
List<DataBindingConditionViewModel<TLayerProperty, TProperty>> toRemove = Items.Where(c => !ConditionalDataBinding.Conditions.Contains(c.DataBindingCondition)).ToList();
|
||||||
|
foreach (DataBindingConditionViewModel<TLayerProperty, TProperty> dataBindingConditionViewModel in toRemove)
|
||||||
|
{
|
||||||
|
Items.Remove(dataBindingConditionViewModel);
|
||||||
|
dataBindingConditionViewModel.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add missing VMs
|
||||||
|
foreach (DataBindingCondition<TLayerProperty, TProperty> condition in ConditionalDataBinding.Conditions)
|
||||||
|
if (Items.All(c => c.DataBindingCondition != condition))
|
||||||
|
Items.Add(_dataBindingsVmFactory.DataBindingConditionViewModel(condition));
|
||||||
|
|
||||||
|
// Fix order
|
||||||
|
((BindableCollection<DataBindingConditionViewModel<TLayerProperty, TProperty>>) Items).Sort(c => c.DataBindingCondition.Order);
|
||||||
|
|
||||||
|
_updating = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Initialize()
|
||||||
|
{
|
||||||
|
ConditionalDataBinding.ConditionsUpdated += ConditionalDataBindingOnConditionsUpdated;
|
||||||
|
Items.CollectionChanged += ItemsOnCollectionChanged;
|
||||||
|
UpdateItems();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ItemsOnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
|
||||||
|
{
|
||||||
|
if (_updating || e.Action != NotifyCollectionChangedAction.Add)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (int index = 0; index < Items.Count; index++)
|
||||||
|
{
|
||||||
|
DataBindingConditionViewModel<TLayerProperty, TProperty> conditionViewModel = Items[index];
|
||||||
|
conditionViewModel.DataBindingCondition.Order = index + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ConditionalDataBinding.ApplyOrder();
|
||||||
|
|
||||||
|
_profileEditorService.UpdateSelectedProfileElement();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ConditionalDataBindingOnConditionsUpdated(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
UpdateItems();
|
||||||
|
}
|
||||||
|
|
||||||
public bool SupportsTestValue => false;
|
public bool SupportsTestValue => false;
|
||||||
|
|
||||||
public void Update()
|
public void Update()
|
||||||
{
|
{
|
||||||
UpdateConditionViewModels();
|
UpdateItems();
|
||||||
}
|
}
|
||||||
|
|
||||||
public object GetTestValue()
|
public object GetTestValue()
|
||||||
@ -49,64 +114,11 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings.Conditio
|
|||||||
{
|
{
|
||||||
ConditionalDataBinding.ConditionsUpdated -= ConditionalDataBindingOnConditionsUpdated;
|
ConditionalDataBinding.ConditionsUpdated -= ConditionalDataBindingOnConditionsUpdated;
|
||||||
|
|
||||||
foreach (DataBindingConditionViewModel<TLayerProperty, TProperty> conditionViewModel in ConditionViewModels)
|
foreach (DataBindingConditionViewModel<TLayerProperty, TProperty> conditionViewModel in Items)
|
||||||
conditionViewModel.Dispose();
|
conditionViewModel.Dispose();
|
||||||
ConditionViewModels.Clear();
|
Items.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
private void UpdateConditionViewModels()
|
|
||||||
{
|
|
||||||
_updating = true;
|
|
||||||
|
|
||||||
// Remove old VMs
|
|
||||||
List<DataBindingConditionViewModel<TLayerProperty, TProperty>> toRemove = ConditionViewModels.Where(c => !ConditionalDataBinding.Conditions.Contains(c.DataBindingCondition)).ToList();
|
|
||||||
foreach (DataBindingConditionViewModel<TLayerProperty, TProperty> dataBindingConditionViewModel in toRemove)
|
|
||||||
{
|
|
||||||
ConditionViewModels.Remove(dataBindingConditionViewModel);
|
|
||||||
dataBindingConditionViewModel.Dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add missing VMs
|
|
||||||
foreach (DataBindingCondition<TLayerProperty, TProperty> condition in ConditionalDataBinding.Conditions)
|
|
||||||
{
|
|
||||||
if (ConditionViewModels.All(c => c.DataBindingCondition != condition))
|
|
||||||
ConditionViewModels.Add(_dataBindingsVmFactory.DataBindingConditionViewModel(condition));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fix order
|
|
||||||
ConditionViewModels.Sort(c => c.DataBindingCondition.Order);
|
|
||||||
|
|
||||||
_updating = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Initialize()
|
|
||||||
{
|
|
||||||
ConditionalDataBinding.ConditionsUpdated += ConditionalDataBindingOnConditionsUpdated;
|
|
||||||
ConditionViewModels.CollectionChanged += ConditionViewModelsOnCollectionChanged;
|
|
||||||
UpdateConditionViewModels();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ConditionViewModelsOnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
|
|
||||||
{
|
|
||||||
if (_updating || e.Action != NotifyCollectionChangedAction.Add)
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (int index = 0; index < ConditionViewModels.Count; index++)
|
|
||||||
{
|
|
||||||
DataBindingConditionViewModel<TLayerProperty, TProperty> conditionViewModel = ConditionViewModels[index];
|
|
||||||
conditionViewModel.DataBindingCondition.Order = index + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
ConditionalDataBinding.ApplyOrder();
|
|
||||||
|
|
||||||
_profileEditorService.UpdateSelectedProfileElement();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ConditionalDataBindingOnConditionsUpdated(object sender, EventArgs e)
|
|
||||||
{
|
|
||||||
UpdateConditionViewModels();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -18,7 +18,7 @@
|
|||||||
IsTabStop="False" />
|
IsTabStop="False" />
|
||||||
|
|
||||||
<ContentControl Grid.Row="1"
|
<ContentControl Grid.Row="1"
|
||||||
Margin="26 5 0 0"
|
Margin="26 2 0 0"
|
||||||
s:View.Model="{Binding ValueViewModel}"
|
s:View.Model="{Binding ValueViewModel}"
|
||||||
VerticalContentAlignment="Stretch"
|
VerticalContentAlignment="Stretch"
|
||||||
HorizontalContentAlignment="Stretch"
|
HorizontalContentAlignment="Stretch"
|
||||||
|
|||||||
@ -13,6 +13,8 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings.Conditio
|
|||||||
public class DataBindingConditionViewModel<TLayerProperty, TProperty> : Conductor<DataModelConditionGroupViewModel>, IDisposable
|
public class DataBindingConditionViewModel<TLayerProperty, TProperty> : Conductor<DataModelConditionGroupViewModel>, IDisposable
|
||||||
{
|
{
|
||||||
private readonly IProfileEditorService _profileEditorService;
|
private readonly IProfileEditorService _profileEditorService;
|
||||||
|
private readonly IDataModelConditionsVmFactory _dataModelConditionsVmFactory;
|
||||||
|
private readonly IDataModelUIService _dataModelUIService;
|
||||||
|
|
||||||
public DataBindingConditionViewModel(DataBindingCondition<TLayerProperty, TProperty> dataBindingCondition,
|
public DataBindingConditionViewModel(DataBindingCondition<TLayerProperty, TProperty> dataBindingCondition,
|
||||||
IProfileEditorService profileEditorService,
|
IProfileEditorService profileEditorService,
|
||||||
@ -20,22 +22,28 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings.Conditio
|
|||||||
IDataModelUIService dataModelUIService)
|
IDataModelUIService dataModelUIService)
|
||||||
{
|
{
|
||||||
_profileEditorService = profileEditorService;
|
_profileEditorService = profileEditorService;
|
||||||
|
_dataModelConditionsVmFactory = dataModelConditionsVmFactory;
|
||||||
|
_dataModelUIService = dataModelUIService;
|
||||||
DataBindingCondition = dataBindingCondition;
|
DataBindingCondition = dataBindingCondition;
|
||||||
|
|
||||||
ActiveItem = dataModelConditionsVmFactory.DataModelConditionGroupViewModel(DataBindingCondition.Condition, ConditionGroupType.General);
|
|
||||||
ActiveItem.IsRootGroup = true;
|
|
||||||
ActiveItem.Update();
|
|
||||||
ActiveItem.Updated += ActiveItemOnUpdated;
|
|
||||||
|
|
||||||
ValueViewModel = dataModelUIService.GetStaticInputViewModel(typeof(TProperty), null);
|
|
||||||
ValueViewModel.ValueUpdated += ValueViewModelOnValueUpdated;
|
|
||||||
ValueViewModel.Value = DataBindingCondition.Value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public DataBindingCondition<TLayerProperty, TProperty> DataBindingCondition { get; }
|
public DataBindingCondition<TLayerProperty, TProperty> DataBindingCondition { get; }
|
||||||
|
|
||||||
public DataModelStaticViewModel ValueViewModel { get; set; }
|
public DataModelStaticViewModel ValueViewModel { get; set; }
|
||||||
|
|
||||||
|
protected override void OnInitialActivate()
|
||||||
|
{
|
||||||
|
base.OnInitialActivate();
|
||||||
|
ActiveItem = _dataModelConditionsVmFactory.DataModelConditionGroupViewModel(DataBindingCondition.Condition, ConditionGroupType.General);
|
||||||
|
ActiveItem.IsRootGroup = true;
|
||||||
|
ActiveItem.Update();
|
||||||
|
ActiveItem.Updated += ActiveItemOnUpdated;
|
||||||
|
|
||||||
|
ValueViewModel = _dataModelUIService.GetStaticInputViewModel(typeof(TProperty), null);
|
||||||
|
ValueViewModel.ValueUpdated += ValueViewModelOnValueUpdated;
|
||||||
|
ValueViewModel.Value = DataBindingCondition.Value;
|
||||||
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
ValueViewModel.Dispose();
|
ValueViewModel.Dispose();
|
||||||
|
|||||||
@ -44,7 +44,11 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
|
|||||||
EasingViewModels = new BindableCollection<TimelineEasingViewModel>();
|
EasingViewModels = new BindableCollection<TimelineEasingViewModel>();
|
||||||
TestInputValue = dataModelUIService.GetDataModelDisplayViewModel(typeof(TProperty), null, true);
|
TestInputValue = dataModelUIService.GetDataModelDisplayViewModel(typeof(TProperty), null, true);
|
||||||
TestResultValue = dataModelUIService.GetDataModelDisplayViewModel(typeof(TProperty), null, true);
|
TestResultValue = dataModelUIService.GetDataModelDisplayViewModel(typeof(TProperty), null, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnInitialActivate()
|
||||||
|
{
|
||||||
|
base.OnInitialActivate();
|
||||||
Initialize();
|
Initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -237,7 +241,7 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
|
|||||||
}
|
}
|
||||||
|
|
||||||
// While playing in preview data bindings aren't updated
|
// While playing in preview data bindings aren't updated
|
||||||
Registration.DataBinding.Update(Registration.LayerProperty.ProfileElement.Timeline);
|
Registration.DataBinding.UpdateWithDelta(TimeSpan.FromMilliseconds(40));
|
||||||
|
|
||||||
if (ActiveItem.SupportsTestValue)
|
if (ActiveItem.SupportsTestValue)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -55,9 +55,9 @@
|
|||||||
DialogTheme="Inherit"
|
DialogTheme="Inherit"
|
||||||
SnackbarMessageQueue="{Binding MainMessageQueue}">
|
SnackbarMessageQueue="{Binding MainMessageQueue}">
|
||||||
|
|
||||||
<materialDesign:DrawerHost IsLeftDrawerOpen="{Binding SidebarViewModel.IsSidebarOpen}">
|
<materialDesign:DrawerHost IsLeftDrawerOpen="{Binding SidebarViewModel.IsSidebarOpen}" >
|
||||||
<materialDesign:DrawerHost.LeftDrawerContent>
|
<materialDesign:DrawerHost.LeftDrawerContent>
|
||||||
<ContentControl s:View.Model="{Binding SidebarViewModel}" Width="280" ClipToBounds="False" />
|
<ContentControl s:View.Model="{Binding SidebarViewModel}" Width="280" />
|
||||||
</materialDesign:DrawerHost.LeftDrawerContent>
|
</materialDesign:DrawerHost.LeftDrawerContent>
|
||||||
<DockPanel>
|
<DockPanel>
|
||||||
<mde:AppBar Type="Dense"
|
<mde:AppBar Type="Dense"
|
||||||
|
|||||||
@ -21,7 +21,7 @@
|
|||||||
<Image Grid.Row="0"
|
<Image Grid.Row="0"
|
||||||
Grid.RowSpan="2"
|
Grid.RowSpan="2"
|
||||||
Source="/Resources/Images/Sidebar/sidebar-header.png"
|
Source="/Resources/Images/Sidebar/sidebar-header.png"
|
||||||
Stretch="None"
|
Stretch="UniformToFill"
|
||||||
VerticalAlignment="Top" Height="120" />
|
VerticalAlignment="Top" Height="120" />
|
||||||
<TextBlock Grid.Row="1"
|
<TextBlock Grid.Row="1"
|
||||||
Style="{StaticResource MaterialDesignHeadline6TextBlock}"
|
Style="{StaticResource MaterialDesignHeadline6TextBlock}"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user