mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-31 17:53:32 +00:00
Profiles - Split conditions into different types
Profile configurations - Added broken state (not yet shown in UI)
This commit is contained in:
parent
8ac1431a2f
commit
d657e7844e
@ -1,4 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using Artemis.Core.Internal;
|
||||||
using Artemis.Storage.Entities.Profile.Conditions;
|
using Artemis.Storage.Entities.Profile.Conditions;
|
||||||
|
|
||||||
namespace Artemis.Core
|
namespace Artemis.Core
|
||||||
@ -8,7 +10,7 @@ namespace Artemis.Core
|
|||||||
private readonly string _displayName;
|
private readonly string _displayName;
|
||||||
private readonly object? _context;
|
private readonly object? _context;
|
||||||
private DateTime _lastProcessedTrigger;
|
private DateTime _lastProcessedTrigger;
|
||||||
private DataModelPath _eventPath;
|
private DataModelPath? _eventPath;
|
||||||
|
|
||||||
internal EventCondition(string displayName, object? context)
|
internal EventCondition(string displayName, object? context)
|
||||||
{
|
{
|
||||||
@ -17,6 +19,7 @@ namespace Artemis.Core
|
|||||||
|
|
||||||
Entity = new EventConditionEntity();
|
Entity = new EventConditionEntity();
|
||||||
Script = new NodeScript<bool>($"Activate {displayName}", $"Whether or not the event should activate the {displayName}", context);
|
Script = new NodeScript<bool>($"Activate {displayName}", $"Whether or not the event should activate the {displayName}", context);
|
||||||
|
UpdateEventNode();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal EventCondition(EventConditionEntity entity, string displayName, object? context)
|
internal EventCondition(EventConditionEntity entity, string displayName, object? context)
|
||||||
@ -38,7 +41,7 @@ namespace Artemis.Core
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the path to the event that drives this event condition
|
/// Gets or sets the path to the event that drives this event condition
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public DataModelPath EventPath
|
public DataModelPath? EventPath
|
||||||
{
|
{
|
||||||
set => SetAndNotify(ref _eventPath, value);
|
set => SetAndNotify(ref _eventPath, value);
|
||||||
get => _eventPath;
|
get => _eventPath;
|
||||||
@ -48,7 +51,7 @@ namespace Artemis.Core
|
|||||||
|
|
||||||
internal bool Evaluate()
|
internal bool Evaluate()
|
||||||
{
|
{
|
||||||
if (EventPath.GetValue() is not DataModelEvent dataModelEvent || dataModelEvent.LastTrigger <= _lastProcessedTrigger)
|
if (EventPath?.GetValue() is not IDataModelEvent dataModelEvent || dataModelEvent.LastTrigger <= _lastProcessedTrigger)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// TODO: Place dataModelEvent.LastEventArgumentsUntyped; in the start node
|
// TODO: Place dataModelEvent.LastEventArgumentsUntyped; in the start node
|
||||||
@ -65,7 +68,7 @@ namespace Artemis.Core
|
|||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
Script.Dispose();
|
Script.Dispose();
|
||||||
EventPath.Dispose();
|
EventPath?.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@ -73,6 +76,25 @@ namespace Artemis.Core
|
|||||||
internal void LoadNodeScript()
|
internal void LoadNodeScript()
|
||||||
{
|
{
|
||||||
Script.Load();
|
Script.Load();
|
||||||
|
UpdateEventNode();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Updates the event node, applying the selected event
|
||||||
|
/// </summary>
|
||||||
|
public void UpdateEventNode()
|
||||||
|
{
|
||||||
|
if (EventPath?.GetValue() is not IDataModelEvent dataModelEvent)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (Script.Nodes.FirstOrDefault(n => n is EventStartNode) is EventStartNode existing)
|
||||||
|
existing.UpdateDataModelEvent(dataModelEvent);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
EventStartNode node = new();
|
||||||
|
node.UpdateDataModelEvent(dataModelEvent);
|
||||||
|
Script.AddNode(node);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Implementation of IStorageModel
|
#region Implementation of IStorageModel
|
||||||
@ -82,13 +104,14 @@ namespace Artemis.Core
|
|||||||
{
|
{
|
||||||
EventPath = new DataModelPath(null, Entity.EventPath);
|
EventPath = new DataModelPath(null, Entity.EventPath);
|
||||||
Script = new NodeScript<bool>($"Activate {_displayName}", $"Whether or not the event should activate the {_displayName}", Entity.Script, _context);
|
Script = new NodeScript<bool>($"Activate {_displayName}", $"Whether or not the event should activate the {_displayName}", Entity.Script, _context);
|
||||||
|
UpdateEventNode();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public void Save()
|
public void Save()
|
||||||
{
|
{
|
||||||
EventPath.Save();
|
EventPath?.Save();
|
||||||
Entity.EventPath = EventPath.Entity;
|
Entity.EventPath = EventPath?.Entity;
|
||||||
Script.Save();
|
Script.Save();
|
||||||
Entity.Script = Script.Entity;
|
Entity.Script = Script.Entity;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Artemis.Storage.Entities.Profile.Abstract;
|
using Artemis.Storage.Entities.Profile.Abstract;
|
||||||
using Artemis.Storage.Entities.Profile.Conditions;
|
using Artemis.Storage.Entities.Profile.Conditions;
|
||||||
@ -18,7 +19,7 @@ namespace Artemis.Core
|
|||||||
_eventsList = new List<EventCondition>();
|
_eventsList = new List<EventCondition>();
|
||||||
|
|
||||||
ProfileElement = profileElement;
|
ProfileElement = profileElement;
|
||||||
Events = new List<EventCondition>(_eventsList);
|
Events = new ReadOnlyCollection<EventCondition>(_eventsList);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal EventsCondition(EventsConditionEntity entity, ProfileElement profileElement)
|
internal EventsCondition(EventsConditionEntity entity, ProfileElement profileElement)
|
||||||
@ -27,7 +28,7 @@ namespace Artemis.Core
|
|||||||
_eventsList = new List<EventCondition>();
|
_eventsList = new List<EventCondition>();
|
||||||
|
|
||||||
ProfileElement = profileElement;
|
ProfileElement = profileElement;
|
||||||
Events = new List<EventCondition>(_eventsList);
|
Events = new ReadOnlyCollection<EventCondition>(_eventsList);
|
||||||
|
|
||||||
Load();
|
Load();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,7 +9,7 @@ namespace Artemis.Core
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents the configuration of a profile, contained in a <see cref="ProfileCategory" />
|
/// Represents the configuration of a profile, contained in a <see cref="ProfileCategory" />
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class ProfileConfiguration : CorePropertyChanged, IStorageModel, IDisposable
|
public class ProfileConfiguration : BreakableModel, IStorageModel, IDisposable
|
||||||
{
|
{
|
||||||
private ProfileCategory _category;
|
private ProfileCategory _category;
|
||||||
private bool _disposed;
|
private bool _disposed;
|
||||||
@ -277,6 +277,13 @@ namespace Artemis.Core
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region Overrides of BreakableModel
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override string BrokenDisplayName => "Profile Configuration";
|
||||||
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@ -221,8 +221,8 @@ namespace Artemis.Core.Services
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Make sure the profile is active or inactive according to the parameters above
|
// Make sure the profile is active or inactive according to the parameters above
|
||||||
if (shouldBeActive && profileConfiguration.Profile == null)
|
if (shouldBeActive && profileConfiguration.Profile == null && profileConfiguration.BrokenState != "Failed to activate profile")
|
||||||
ActivateProfile(profileConfiguration);
|
profileConfiguration.TryOrBreak(() => ActivateProfile(profileConfiguration), "Failed to activate profile");
|
||||||
else if (!shouldBeActive && profileConfiguration.Profile != null)
|
else if (!shouldBeActive && profileConfiguration.Profile != null)
|
||||||
DeactivateProfile(profileConfiguration);
|
DeactivateProfile(profileConfiguration);
|
||||||
|
|
||||||
|
|||||||
@ -10,6 +10,7 @@ namespace Artemis.Core
|
|||||||
string Name { get; }
|
string Name { get; }
|
||||||
string Description { get; }
|
string Description { get; }
|
||||||
bool IsExitNode { get; }
|
bool IsExitNode { get; }
|
||||||
|
bool IsDefaultNode { get; }
|
||||||
|
|
||||||
public double X { get; set; }
|
public double X { get; set; }
|
||||||
public double Y { get; set; }
|
public double Y { get; set; }
|
||||||
|
|||||||
49
src/Artemis.Core/VisualScripting/Internal/EventStartNode.cs
Normal file
49
src/Artemis.Core/VisualScripting/Internal/EventStartNode.cs
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using Humanizer;
|
||||||
|
|
||||||
|
namespace Artemis.Core.Internal
|
||||||
|
{
|
||||||
|
internal class EventStartNode : Node
|
||||||
|
{
|
||||||
|
private IDataModelEvent? _dataModelEvent;
|
||||||
|
private readonly Dictionary<PropertyInfo, OutputPin> _propertyPins;
|
||||||
|
|
||||||
|
public EventStartNode() : base("Event Arguments", "Contains the event arguments that triggered the evaluation")
|
||||||
|
{
|
||||||
|
_propertyPins = new Dictionary<PropertyInfo, OutputPin>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateDataModelEvent(IDataModelEvent dataModelEvent)
|
||||||
|
{
|
||||||
|
if (_dataModelEvent == dataModelEvent)
|
||||||
|
return;
|
||||||
|
|
||||||
|
foreach (var (_, outputPin) in _propertyPins)
|
||||||
|
RemovePin(outputPin);
|
||||||
|
_propertyPins.Clear();
|
||||||
|
|
||||||
|
_dataModelEvent = dataModelEvent;
|
||||||
|
foreach (PropertyInfo propertyInfo in dataModelEvent.ArgumentsType.GetProperties(BindingFlags.Instance | BindingFlags.Public))
|
||||||
|
_propertyPins.Add(propertyInfo, CreateOutputPin(propertyInfo.PropertyType, propertyInfo.Name.Humanize()));
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Overrides of Node
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void Evaluate()
|
||||||
|
{
|
||||||
|
if (_dataModelEvent?.LastEventArgumentsUntyped == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
foreach (var (propertyInfo, outputPin) in _propertyPins)
|
||||||
|
{
|
||||||
|
if (outputPin.ConnectedTo.Any())
|
||||||
|
outputPin.Value = propertyInfo.GetValue(_dataModelEvent.LastEventArgumentsUntyped) ?? outputPin.Type.GetDefault()!;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -25,6 +25,7 @@ namespace Artemis.Core
|
|||||||
}
|
}
|
||||||
|
|
||||||
private double _x;
|
private double _x;
|
||||||
|
|
||||||
public double X
|
public double X
|
||||||
{
|
{
|
||||||
get => _x;
|
get => _x;
|
||||||
@ -46,6 +47,7 @@ namespace Artemis.Core
|
|||||||
}
|
}
|
||||||
|
|
||||||
public virtual bool IsExitNode => false;
|
public virtual bool IsExitNode => false;
|
||||||
|
public virtual bool IsDefaultNode => false;
|
||||||
|
|
||||||
private readonly List<IPin> _pins = new();
|
private readonly List<IPin> _pins = new();
|
||||||
public IReadOnlyCollection<IPin> Pins => new ReadOnlyCollection<IPin>(_pins);
|
public IReadOnlyCollection<IPin> Pins => new ReadOnlyCollection<IPin>(_pins);
|
||||||
|
|||||||
@ -3,6 +3,8 @@ using Artemis.Core.Modules;
|
|||||||
using Artemis.Core.ScriptingProviders;
|
using Artemis.Core.ScriptingProviders;
|
||||||
using Artemis.UI.Screens.Header;
|
using Artemis.UI.Screens.Header;
|
||||||
using Artemis.UI.Screens.Plugins;
|
using Artemis.UI.Screens.Plugins;
|
||||||
|
using Artemis.UI.Screens.ProfileEditor.DisplayConditions.Event;
|
||||||
|
using Artemis.UI.Screens.ProfileEditor.DisplayConditions.Static;
|
||||||
using Artemis.UI.Screens.ProfileEditor.LayerProperties;
|
using Artemis.UI.Screens.ProfileEditor.LayerProperties;
|
||||||
using Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings;
|
using Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings;
|
||||||
using Artemis.UI.Screens.ProfileEditor.LayerProperties.LayerEffects;
|
using Artemis.UI.Screens.ProfileEditor.LayerProperties.LayerEffects;
|
||||||
@ -92,6 +94,13 @@ namespace Artemis.UI.Ninject.Factories
|
|||||||
TimelineSegmentViewModel TimelineSegmentViewModel(SegmentViewModelType segment, IObservableCollection<LayerPropertyGroupViewModel> layerPropertyGroups);
|
TimelineSegmentViewModel TimelineSegmentViewModel(SegmentViewModelType segment, IObservableCollection<LayerPropertyGroupViewModel> layerPropertyGroups);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public interface IConditionVmFactory : IVmFactory
|
||||||
|
{
|
||||||
|
StaticConditionViewModel StaticConditionViewModel(StaticCondition staticCondition);
|
||||||
|
EventsConditionViewModel EventsConditionViewModel(EventsCondition eventsCondition);
|
||||||
|
EventConditionViewModel EventConditionViewModel(EventCondition eventCondition);
|
||||||
|
}
|
||||||
|
|
||||||
public interface IPrerequisitesVmFactory : IVmFactory
|
public interface IPrerequisitesVmFactory : IVmFactory
|
||||||
{
|
{
|
||||||
PluginPrerequisiteViewModel PluginPrerequisiteViewModel(PluginPrerequisite pluginPrerequisite, bool uninstall);
|
PluginPrerequisiteViewModel PluginPrerequisiteViewModel(PluginPrerequisite pluginPrerequisite, bool uninstall);
|
||||||
|
|||||||
@ -1,13 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Stylet;
|
|
||||||
|
|
||||||
namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
|
|
||||||
{
|
|
||||||
public class DisplayConditionEventViewModel : Screen
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -37,10 +37,28 @@
|
|||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition />
|
<ColumnDefinition />
|
||||||
<ColumnDefinition />
|
<ColumnDefinition />
|
||||||
|
<ColumnDefinition />
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
<RadioButton Grid.Column="0"
|
<RadioButton Grid.Column="0"
|
||||||
Style="{StaticResource MaterialDesignTabRadioButton}"
|
Style="{StaticResource MaterialDesignTabRadioButton}"
|
||||||
IsChecked="{Binding IsEventCondition, Converter={StaticResource InverseBooleanConverter}}"
|
IsChecked="{Binding Path=DisplayConditionType, Converter={StaticResource ComparisonConverter}, ConverterParameter={x:Static displayConditions:DisplayConditionType.None}}"
|
||||||
|
MinWidth="0"
|
||||||
|
Padding="10 0">
|
||||||
|
<RadioButton.ToolTip>
|
||||||
|
<ToolTip Placement="Center" VerticalOffset="-40">
|
||||||
|
<TextBlock>
|
||||||
|
No condition, the element is always displayed
|
||||||
|
</TextBlock>
|
||||||
|
</ToolTip>
|
||||||
|
</RadioButton.ToolTip>
|
||||||
|
<TextBlock VerticalAlignment="Center" FontSize="12">
|
||||||
|
<materialDesign:PackIcon Kind="Close" VerticalAlignment="Center" Margin="0 0 2 -3" />
|
||||||
|
NONE
|
||||||
|
</TextBlock>
|
||||||
|
</RadioButton>
|
||||||
|
<RadioButton Grid.Column="1"
|
||||||
|
Style="{StaticResource MaterialDesignTabRadioButton}"
|
||||||
|
IsChecked="{Binding Path=DisplayConditionType, Converter={StaticResource ComparisonConverter}, ConverterParameter={x:Static displayConditions:DisplayConditionType.Static}}"
|
||||||
MinWidth="0"
|
MinWidth="0"
|
||||||
Padding="10 0">
|
Padding="10 0">
|
||||||
<RadioButton.ToolTip>
|
<RadioButton.ToolTip>
|
||||||
@ -55,9 +73,9 @@
|
|||||||
CONSTANT
|
CONSTANT
|
||||||
</TextBlock>
|
</TextBlock>
|
||||||
</RadioButton>
|
</RadioButton>
|
||||||
<RadioButton Grid.Column="1"
|
<RadioButton Grid.Column="2"
|
||||||
Style="{StaticResource MaterialDesignTabRadioButton}"
|
Style="{StaticResource MaterialDesignTabRadioButton}"
|
||||||
IsChecked="{Binding IsEventCondition}"
|
IsChecked="{Binding Path=DisplayConditionType, Converter={StaticResource ComparisonConverter}, ConverterParameter={x:Static displayConditions:DisplayConditionType.Events}}"
|
||||||
MinWidth="0"
|
MinWidth="0"
|
||||||
Padding="10 0">
|
Padding="10 0">
|
||||||
<RadioButton.ToolTip>
|
<RadioButton.ToolTip>
|
||||||
@ -78,200 +96,10 @@
|
|||||||
|
|
||||||
<Separator Grid.Row="1" Grid.Column="0" Style="{StaticResource MaterialDesignDarkSeparator}" Margin="-2 0" />
|
<Separator Grid.Row="1" Grid.Column="0" Style="{StaticResource MaterialDesignDarkSeparator}" Margin="-2 0" />
|
||||||
|
|
||||||
<Grid Grid.Row="2" Visibility="{Binding IsEventCondition, Converter={x:Static s:BoolToVisibilityConverter.InverseInstance}, Mode=OneWay}">
|
<ContentControl Grid.Row="2"
|
||||||
<Grid.RowDefinitions>
|
s:View.Model="{Binding ActiveItem}"
|
||||||
<RowDefinition Height="*" />
|
VerticalContentAlignment="Stretch"
|
||||||
<RowDefinition Height="Auto" />
|
HorizontalContentAlignment="Stretch"
|
||||||
</Grid.RowDefinitions>
|
IsTabStop="False"/>
|
||||||
|
|
||||||
<Grid Grid.Row="0" MouseUp="{s:Action ScriptGridMouseUp}" Cursor="Hand">
|
|
||||||
<controls:VisualScriptPresenter Script="{Binding RenderProfileElement.DisplayCondition}"
|
|
||||||
AutoFitScript="True"
|
|
||||||
Visibility="{Binding RenderProfileElement.DisplayCondition, Converter={StaticResource NullToVisibilityConverter}}" />
|
|
||||||
<Border Opacity="0">
|
|
||||||
<Border.Background>
|
|
||||||
<SolidColorBrush Color="{Binding Color, Source={StaticResource MaterialDesignCardBackground}}" Opacity="0.75" />
|
|
||||||
</Border.Background>
|
|
||||||
<Border.Style>
|
|
||||||
<Style>
|
|
||||||
<Style.Triggers>
|
|
||||||
<DataTrigger Binding="{Binding IsMouseOver, RelativeSource={RelativeSource AncestorType={x:Type Grid}, Mode=FindAncestor}}" Value="True">
|
|
||||||
<DataTrigger.EnterActions>
|
|
||||||
<BeginStoryboard>
|
|
||||||
<Storyboard>
|
|
||||||
<DoubleAnimation Storyboard.TargetProperty="Opacity" To="1" Duration="0:0:0.25" />
|
|
||||||
</Storyboard>
|
|
||||||
</BeginStoryboard>
|
|
||||||
</DataTrigger.EnterActions>
|
|
||||||
<DataTrigger.ExitActions>
|
|
||||||
<BeginStoryboard>
|
|
||||||
<Storyboard>
|
|
||||||
<DoubleAnimation Storyboard.TargetProperty="Opacity" To="0" Duration="0:0:0.25" />
|
|
||||||
</Storyboard>
|
|
||||||
</BeginStoryboard>
|
|
||||||
</DataTrigger.ExitActions>
|
|
||||||
</DataTrigger>
|
|
||||||
</Style.Triggers>
|
|
||||||
</Style>
|
|
||||||
</Border.Style>
|
|
||||||
<Grid HorizontalAlignment="Center">
|
|
||||||
<Grid.ColumnDefinitions>
|
|
||||||
<ColumnDefinition />
|
|
||||||
<ColumnDefinition />
|
|
||||||
</Grid.ColumnDefinitions>
|
|
||||||
<TextBlock Style="{StaticResource MaterialDesignHeadline5TextBlock}" VerticalAlignment="Center" Grid.Column="0">
|
|
||||||
Click to edit script
|
|
||||||
</TextBlock>
|
|
||||||
<materialDesign:PackIcon Kind="OpenInNew" Margin="10 " Width="30" Height="30" Grid.Column="1" VerticalAlignment="Center" />
|
|
||||||
</Grid>
|
|
||||||
</Border>
|
|
||||||
</Grid>
|
|
||||||
<Grid Grid.Row="1">
|
|
||||||
<Grid.RowDefinitions>
|
|
||||||
<RowDefinition Height="22" />
|
|
||||||
<RowDefinition />
|
|
||||||
</Grid.RowDefinitions>
|
|
||||||
<Grid.ColumnDefinitions>
|
|
||||||
<ColumnDefinition Width="*" MinWidth="140" />
|
|
||||||
<ColumnDefinition Width="*" MinWidth="170" />
|
|
||||||
</Grid.ColumnDefinitions>
|
|
||||||
|
|
||||||
<!-- Play mode -->
|
|
||||||
<TextBlock Grid.Column="0" Text="Play mode" VerticalAlignment="Center">
|
|
||||||
<TextBlock.ToolTip>
|
|
||||||
<ToolTip Placement="Center" VerticalOffset="-30">
|
|
||||||
<TextBlock>
|
|
||||||
Configure how the layer should act while the conditions above are met
|
|
||||||
</TextBlock>
|
|
||||||
</ToolTip>
|
|
||||||
</TextBlock.ToolTip>
|
|
||||||
</TextBlock>
|
|
||||||
<materialDesign:ColorZone Grid.Row="1" Grid.Column="0" Mode="Standard" CornerRadius="3" Margin="0 0 2 0">
|
|
||||||
<Grid>
|
|
||||||
<Grid.ColumnDefinitions>
|
|
||||||
<ColumnDefinition />
|
|
||||||
<ColumnDefinition />
|
|
||||||
</Grid.ColumnDefinitions>
|
|
||||||
<RadioButton Grid.Column="0"
|
|
||||||
Style="{StaticResource MaterialDesignTabRadioButton}"
|
|
||||||
IsChecked="{Binding DisplayContinuously}"
|
|
||||||
MinWidth="0"
|
|
||||||
Padding="5 0">
|
|
||||||
<RadioButton.ToolTip>
|
|
||||||
<ToolTip Placement="Center" VerticalOffset="-40">
|
|
||||||
<TextBlock>
|
|
||||||
Continue repeating the main segment of the timeline while the condition is met
|
|
||||||
</TextBlock>
|
|
||||||
</ToolTip>
|
|
||||||
</RadioButton.ToolTip>
|
|
||||||
<TextBlock VerticalAlignment="Center" FontSize="12">
|
|
||||||
<materialDesign:PackIcon Kind="Repeat" VerticalAlignment="Center" Margin="-3 0 0 -3" />
|
|
||||||
REPEAT
|
|
||||||
</TextBlock>
|
|
||||||
</RadioButton>
|
|
||||||
<RadioButton Grid.Column="1"
|
|
||||||
Style="{StaticResource MaterialDesignTabRadioButton}"
|
|
||||||
IsChecked="{Binding DisplayContinuously, Converter={StaticResource InverseBooleanConverter}}"
|
|
||||||
MinWidth="0"
|
|
||||||
Padding="5 0">
|
|
||||||
<RadioButton.ToolTip>
|
|
||||||
<ToolTip Placement="Center" VerticalOffset="-40">
|
|
||||||
<TextBlock>
|
|
||||||
Only play the timeline once when the condition is met
|
|
||||||
</TextBlock>
|
|
||||||
</ToolTip>
|
|
||||||
</RadioButton.ToolTip>
|
|
||||||
<TextBlock VerticalAlignment="Center" FontSize="12">
|
|
||||||
<materialDesign:PackIcon Kind="StopwatchOutline" VerticalAlignment="Center" Margin="-3 0 0 -3" />
|
|
||||||
ONCE
|
|
||||||
</TextBlock>
|
|
||||||
</RadioButton>
|
|
||||||
</Grid>
|
|
||||||
</materialDesign:ColorZone>
|
|
||||||
|
|
||||||
<!-- Stop mode -->
|
|
||||||
<TextBlock Grid.Row="0" Grid.Column="1" Text="Stop mode">
|
|
||||||
<TextBlock.ToolTip>
|
|
||||||
<ToolTip Placement="Center" VerticalOffset="-30">
|
|
||||||
<TextBlock>
|
|
||||||
Configure how the layer should act when the conditions above are no longer met
|
|
||||||
</TextBlock>
|
|
||||||
</ToolTip>
|
|
||||||
</TextBlock.ToolTip>
|
|
||||||
</TextBlock>
|
|
||||||
<materialDesign:ColorZone Grid.Row="1" Grid.Column="1" Mode="Standard" CornerRadius="3" Margin="2 0 0 0" HorizontalAlignment="Stretch">
|
|
||||||
<Grid>
|
|
||||||
<Grid.ColumnDefinitions>
|
|
||||||
<ColumnDefinition />
|
|
||||||
<ColumnDefinition MinWidth="100" />
|
|
||||||
</Grid.ColumnDefinitions>
|
|
||||||
<RadioButton Grid.Column="0"
|
|
||||||
Style="{StaticResource MaterialDesignTabRadioButton}"
|
|
||||||
IsChecked="{Binding AlwaysFinishTimeline}"
|
|
||||||
MinWidth="0"
|
|
||||||
Padding="5 0">
|
|
||||||
<RadioButton.ToolTip>
|
|
||||||
<ToolTip Placement="Center" VerticalOffset="-40">
|
|
||||||
<TextBlock>
|
|
||||||
When conditions are no longer met, finish the the current run of the main timeline
|
|
||||||
</TextBlock>
|
|
||||||
</ToolTip>
|
|
||||||
</RadioButton.ToolTip>
|
|
||||||
<TextBlock VerticalAlignment="Center" FontSize="12">
|
|
||||||
<materialDesign:PackIcon Kind="PlayOutline" VerticalAlignment="Center" Margin="-3 0 0 -3" />
|
|
||||||
FINISH
|
|
||||||
</TextBlock>
|
|
||||||
</RadioButton>
|
|
||||||
<RadioButton Grid.Column="1"
|
|
||||||
Style="{StaticResource MaterialDesignTabRadioButton}"
|
|
||||||
IsChecked="{Binding AlwaysFinishTimeline, Converter={StaticResource InverseBooleanConverter}}"
|
|
||||||
MinWidth="0"
|
|
||||||
Padding="5 0">
|
|
||||||
<RadioButton.ToolTip>
|
|
||||||
<ToolTip Placement="Center" VerticalOffset="-40">
|
|
||||||
<TextBlock>
|
|
||||||
When conditions are no longer met, skip to the end segment of the timeline
|
|
||||||
</TextBlock>
|
|
||||||
</ToolTip>
|
|
||||||
</RadioButton.ToolTip>
|
|
||||||
<TextBlock VerticalAlignment="Center" FontSize="12">
|
|
||||||
<materialDesign:PackIcon Kind="SkipNextOutline" VerticalAlignment="Center" Margin="-3 0 0 -3" />
|
|
||||||
SKIP TO END
|
|
||||||
</TextBlock>
|
|
||||||
</RadioButton>
|
|
||||||
</Grid>
|
|
||||||
</materialDesign:ColorZone>
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
|
|
||||||
<TabControl Grid.Row="2"
|
|
||||||
Visibility="{Binding IsEventCondition, Converter={x:Static s:BoolToVisibilityConverter.Instance}, Mode=OneWay}"
|
|
||||||
ItemsSource="{Binding Items}"
|
|
||||||
SelectedItem="{Binding ActiveItem}"
|
|
||||||
Style="{StaticResource MaterialDesignTabControl}"
|
|
||||||
Background="{DynamicResource MaterialDesignPaper}">
|
|
||||||
<TabControl.ItemTemplate>
|
|
||||||
<DataTemplate>
|
|
||||||
<DockPanel LastChildFill="True" Margin="-15 0">
|
|
||||||
<Button DockPanel.Dock="Right"
|
|
||||||
Style="{StaticResource MaterialDesignIconForegroundButton}"
|
|
||||||
Width="25"
|
|
||||||
Height="25">
|
|
||||||
<materialDesign:PackIcon Kind="Close" Width="15" Height="15" Foreground="{DynamicResource MaterialDesignBody}" />
|
|
||||||
</Button>
|
|
||||||
<Label Content="{Binding DisplayName}" DockPanel.Dock="Left" />
|
|
||||||
</DockPanel>
|
|
||||||
</DataTemplate>
|
|
||||||
</TabControl.ItemTemplate>
|
|
||||||
<TabControl.ContentTemplate>
|
|
||||||
<DataTemplate>
|
|
||||||
<ContentControl s:View.Model="{Binding IsAsync=True}"
|
|
||||||
VerticalContentAlignment="Stretch"
|
|
||||||
HorizontalContentAlignment="Stretch"
|
|
||||||
IsTabStop="False"
|
|
||||||
TextElement.Foreground="{DynamicResource MaterialDesignBody}" />
|
|
||||||
</DataTemplate>
|
|
||||||
</TabControl.ContentTemplate>
|
|
||||||
</TabControl>
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</UserControl>
|
</UserControl>
|
||||||
@ -1,6 +1,4 @@
|
|||||||
using System.ComponentModel;
|
using Artemis.Core;
|
||||||
using System.Windows.Input;
|
|
||||||
using Artemis.Core;
|
|
||||||
using Artemis.UI.Ninject.Factories;
|
using Artemis.UI.Ninject.Factories;
|
||||||
using Artemis.UI.Shared;
|
using Artemis.UI.Shared;
|
||||||
using Artemis.UI.Shared.Services;
|
using Artemis.UI.Shared.Services;
|
||||||
@ -8,84 +6,31 @@ using Stylet;
|
|||||||
|
|
||||||
namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
|
namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
|
||||||
{
|
{
|
||||||
public class DisplayConditionsViewModel : Conductor<DisplayConditionEventViewModel>.Collection.OneActive, IProfileEditorPanelViewModel
|
public class DisplayConditionsViewModel : Conductor<Screen>, IProfileEditorPanelViewModel
|
||||||
{
|
{
|
||||||
private readonly INodeVmFactory _nodeVmFactory;
|
private readonly IConditionVmFactory _conditionVmFactory;
|
||||||
private readonly IProfileEditorService _profileEditorService;
|
private readonly IProfileEditorService _profileEditorService;
|
||||||
private readonly IWindowManager _windowManager;
|
private DisplayConditionType _displayConditionType;
|
||||||
private bool _isEventCondition;
|
|
||||||
private RenderProfileElement _renderProfileElement;
|
|
||||||
|
|
||||||
public DisplayConditionsViewModel(IProfileEditorService profileEditorService, IWindowManager windowManager, INodeVmFactory nodeVmFactory)
|
public DisplayConditionsViewModel(IProfileEditorService profileEditorService, IConditionVmFactory conditionVmFactory)
|
||||||
{
|
{
|
||||||
_profileEditorService = profileEditorService;
|
_profileEditorService = profileEditorService;
|
||||||
_windowManager = windowManager;
|
_conditionVmFactory = conditionVmFactory;
|
||||||
_nodeVmFactory = nodeVmFactory;
|
|
||||||
|
|
||||||
Items.Add(new DisplayConditionEventViewModel() { DisplayName = "Event 1"});
|
|
||||||
Items.Add(new DisplayConditionEventViewModel() { DisplayName = "Event 2"});
|
|
||||||
Items.Add(new DisplayConditionEventViewModel() { DisplayName = "Event 3"});
|
|
||||||
Items.Add(new DisplayConditionEventViewModel() { DisplayName = "Event 4"});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsEventCondition
|
public DisplayConditionType DisplayConditionType
|
||||||
{
|
{
|
||||||
get => _isEventCondition;
|
get => _displayConditionType;
|
||||||
set => SetAndNotify(ref _isEventCondition, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public RenderProfileElement RenderProfileElement
|
|
||||||
{
|
|
||||||
get => _renderProfileElement;
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (!SetAndNotify(ref _renderProfileElement, value)) return;
|
if (!SetAndNotify(ref _displayConditionType, value)) return;
|
||||||
NotifyOfPropertyChange(nameof(DisplayContinuously));
|
ChangeConditionType();
|
||||||
NotifyOfPropertyChange(nameof(AlwaysFinishTimeline));
|
|
||||||
NotifyOfPropertyChange(nameof(EventOverlapMode));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool DisplayContinuously
|
|
||||||
{
|
|
||||||
get => RenderProfileElement?.Timeline.PlayMode == TimelinePlayMode.Repeat;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
TimelinePlayMode playMode = value ? TimelinePlayMode.Repeat : TimelinePlayMode.Once;
|
|
||||||
if (RenderProfileElement == null || RenderProfileElement?.Timeline.PlayMode == playMode) return;
|
|
||||||
RenderProfileElement.Timeline.PlayMode = playMode;
|
|
||||||
_profileEditorService.SaveSelectedProfileElement();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool AlwaysFinishTimeline
|
|
||||||
{
|
|
||||||
get => RenderProfileElement?.Timeline.StopMode == TimelineStopMode.Finish;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
TimelineStopMode stopMode = value ? TimelineStopMode.Finish : TimelineStopMode.SkipToEnd;
|
|
||||||
if (RenderProfileElement == null || RenderProfileElement?.Timeline.StopMode == stopMode) return;
|
|
||||||
RenderProfileElement.Timeline.StopMode = stopMode;
|
|
||||||
_profileEditorService.SaveSelectedProfileElement();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public TimeLineEventOverlapMode EventOverlapMode
|
|
||||||
{
|
|
||||||
get => RenderProfileElement?.Timeline.EventOverlapMode ?? TimeLineEventOverlapMode.Restart;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (RenderProfileElement == null || RenderProfileElement?.Timeline.EventOverlapMode == value) return;
|
|
||||||
RenderProfileElement.Timeline.EventOverlapMode = value;
|
|
||||||
_profileEditorService.SaveSelectedProfileElement();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool ConditionBehaviourEnabled => RenderProfileElement != null;
|
|
||||||
|
|
||||||
protected override void OnInitialActivate()
|
protected override void OnInitialActivate()
|
||||||
{
|
{
|
||||||
_profileEditorService.SelectedProfileElementChanged += SelectedProfileEditorServiceOnSelectedProfileElementChanged;
|
_profileEditorService.SelectedProfileElementChanged += ProfileEditorServiceOnSelectedProfileElementChanged;
|
||||||
Update(_profileEditorService.SelectedProfileElement);
|
Update(_profileEditorService.SelectedProfileElement);
|
||||||
|
|
||||||
base.OnInitialActivate();
|
base.OnInitialActivate();
|
||||||
@ -93,55 +38,63 @@ namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
|
|||||||
|
|
||||||
protected override void OnClose()
|
protected override void OnClose()
|
||||||
{
|
{
|
||||||
_profileEditorService.SelectedProfileElementChanged -= SelectedProfileEditorServiceOnSelectedProfileElementChanged;
|
_profileEditorService.SelectedProfileElementChanged -= ProfileEditorServiceOnSelectedProfileElementChanged;
|
||||||
base.OnClose();
|
base.OnClose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void ChangeConditionType()
|
||||||
|
{
|
||||||
|
if (_profileEditorService.SelectedProfileElement == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (DisplayConditionType == DisplayConditionType.Static)
|
||||||
|
_profileEditorService.SelectedProfileElement.ChangeDisplayCondition(new StaticCondition(_profileEditorService.SelectedProfileElement));
|
||||||
|
else if (DisplayConditionType == DisplayConditionType.Events)
|
||||||
|
_profileEditorService.SelectedProfileElement.ChangeDisplayCondition(new EventsCondition(_profileEditorService.SelectedProfileElement));
|
||||||
|
else
|
||||||
|
_profileEditorService.SelectedProfileElement.ChangeDisplayCondition(null);
|
||||||
|
|
||||||
|
_profileEditorService.SaveSelectedProfileElement();
|
||||||
|
Update(_profileEditorService.SelectedProfileElement);
|
||||||
|
}
|
||||||
|
|
||||||
private void Update(RenderProfileElement renderProfileElement)
|
private void Update(RenderProfileElement renderProfileElement)
|
||||||
{
|
{
|
||||||
if (RenderProfileElement != null)
|
if (renderProfileElement == null)
|
||||||
RenderProfileElement.Timeline.PropertyChanged -= TimelineOnPropertyChanged;
|
{
|
||||||
|
ActiveItem = null;
|
||||||
RenderProfileElement = renderProfileElement;
|
|
||||||
|
|
||||||
NotifyOfPropertyChange(nameof(DisplayContinuously));
|
|
||||||
NotifyOfPropertyChange(nameof(AlwaysFinishTimeline));
|
|
||||||
NotifyOfPropertyChange(nameof(ConditionBehaviourEnabled));
|
|
||||||
|
|
||||||
if (RenderProfileElement != null)
|
|
||||||
RenderProfileElement.Timeline.PropertyChanged += TimelineOnPropertyChanged;
|
|
||||||
}
|
|
||||||
|
|
||||||
#region Event handlers
|
|
||||||
|
|
||||||
public void ScriptGridMouseUp(object sender, MouseButtonEventArgs e)
|
|
||||||
{
|
|
||||||
if (e.ChangedButton != MouseButton.Left)
|
|
||||||
return;
|
|
||||||
if (RenderProfileElement == null)
|
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// _windowManager.ShowDialog(_nodeVmFactory.NodeScriptWindowViewModel(RenderProfileElement.DisplayCondition));
|
if (renderProfileElement.DisplayCondition is StaticCondition staticCondition)
|
||||||
_profileEditorService.SaveSelectedProfileElement();
|
{
|
||||||
|
ActiveItem = _conditionVmFactory.StaticConditionViewModel(staticCondition);
|
||||||
|
_displayConditionType = DisplayConditionType.Static;
|
||||||
|
}
|
||||||
|
else if (renderProfileElement.DisplayCondition is EventsCondition eventsCondition)
|
||||||
|
{
|
||||||
|
ActiveItem = _conditionVmFactory.EventsConditionViewModel(eventsCondition);
|
||||||
|
_displayConditionType = DisplayConditionType.Events;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ActiveItem = null;
|
||||||
|
_displayConditionType = DisplayConditionType.None;
|
||||||
|
}
|
||||||
|
|
||||||
|
NotifyOfPropertyChange(nameof(DisplayConditionType));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void EventTriggerModeSelected()
|
private void ProfileEditorServiceOnSelectedProfileElementChanged(object sender, RenderProfileElementEventArgs e)
|
||||||
{
|
|
||||||
_profileEditorService.SaveSelectedProfileElement();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SelectedProfileEditorServiceOnSelectedProfileElementChanged(object sender, RenderProfileElementEventArgs e)
|
|
||||||
{
|
{
|
||||||
Update(e.RenderProfileElement);
|
Update(e.RenderProfileElement);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void TimelineOnPropertyChanged(object sender, PropertyChangedEventArgs e)
|
public enum DisplayConditionType
|
||||||
{
|
{
|
||||||
NotifyOfPropertyChange(nameof(DisplayContinuously));
|
None,
|
||||||
NotifyOfPropertyChange(nameof(AlwaysFinishTimeline));
|
Static,
|
||||||
NotifyOfPropertyChange(nameof(EventOverlapMode));
|
Events
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -0,0 +1,81 @@
|
|||||||
|
<UserControl x:Class="Artemis.UI.Screens.ProfileEditor.DisplayConditions.Event.EventConditionView"
|
||||||
|
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:local="clr-namespace:Artemis.UI.Screens.ProfileEditor.DisplayConditions.Event"
|
||||||
|
xmlns:s="https://github.com/canton7/Stylet"
|
||||||
|
xmlns:controls="clr-namespace:Artemis.VisualScripting.Editor.Controls;assembly=Artemis.VisualScripting"
|
||||||
|
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||||
|
xmlns:shared="clr-namespace:Artemis.UI.Shared.Controls;assembly=Artemis.UI.Shared"
|
||||||
|
mc:Ignorable="d"
|
||||||
|
d:DesignHeight="450" d:DesignWidth="800"
|
||||||
|
d:DataContext="{d:DesignInstance {x:Type local:EventConditionViewModel}}">
|
||||||
|
<Grid>
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition />
|
||||||
|
<ColumnDefinition />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="*" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
|
<shared:DataModelPicker Grid.Row="0"
|
||||||
|
Grid.Column="0"
|
||||||
|
Margin="0 5"
|
||||||
|
ButtonBrush="DarkGoldenrod"
|
||||||
|
DataModelPath="{Binding EventCondition.EventPath}"
|
||||||
|
DataModelPathSelected="{s:Action DataModelPathSelected}"
|
||||||
|
FilterTypes="{Binding FilterTypes}"
|
||||||
|
Modules="{Binding Modules}" />
|
||||||
|
<Button Grid.Row="0"
|
||||||
|
Grid.Column="1"
|
||||||
|
Margin="0 5"
|
||||||
|
Command="{s:Action AddEvent}"
|
||||||
|
s:View.ActionTarget="{Binding Parent}"
|
||||||
|
Content="ADD EVENT" />
|
||||||
|
|
||||||
|
<Grid Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" MouseUp="{s:Action ScriptGridMouseUp}" Cursor="Hand">
|
||||||
|
<controls:VisualScriptPresenter Script="{Binding EventCondition.Script}" AutoFitScript="True" />
|
||||||
|
<Border VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
|
||||||
|
<Border.Background>
|
||||||
|
<SolidColorBrush Color="{Binding Color, Source={StaticResource MaterialDesignPaper}}" Opacity="0.75" />
|
||||||
|
</Border.Background>
|
||||||
|
<Border.Style>
|
||||||
|
<Style>
|
||||||
|
<Style.Triggers>
|
||||||
|
<DataTrigger Binding="{Binding IsMouseOver, RelativeSource={RelativeSource AncestorType={x:Type Grid}, Mode=FindAncestor}}" Value="True">
|
||||||
|
<DataTrigger.EnterActions>
|
||||||
|
<BeginStoryboard>
|
||||||
|
<Storyboard>
|
||||||
|
<DoubleAnimation Storyboard.TargetProperty="Opacity" To="1" Duration="0:0:0.25" />
|
||||||
|
</Storyboard>
|
||||||
|
</BeginStoryboard>
|
||||||
|
</DataTrigger.EnterActions>
|
||||||
|
<DataTrigger.ExitActions>
|
||||||
|
<BeginStoryboard>
|
||||||
|
<Storyboard>
|
||||||
|
<DoubleAnimation Storyboard.TargetProperty="Opacity" To="0" Duration="0:0:0.25" />
|
||||||
|
</Storyboard>
|
||||||
|
</BeginStoryboard>
|
||||||
|
</DataTrigger.ExitActions>
|
||||||
|
</DataTrigger>
|
||||||
|
</Style.Triggers>
|
||||||
|
</Style>
|
||||||
|
</Border.Style>
|
||||||
|
<Grid HorizontalAlignment="Center">
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition />
|
||||||
|
<ColumnDefinition />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<TextBlock Style="{StaticResource MaterialDesignHeadline5TextBlock}" VerticalAlignment="Center" Grid.Column="0">
|
||||||
|
Click to edit script
|
||||||
|
</TextBlock>
|
||||||
|
<materialDesign:PackIcon Kind="OpenInNew" Margin="10 " Width="30" Height="30" Grid.Column="1" VerticalAlignment="Center" />
|
||||||
|
</Grid>
|
||||||
|
</Border>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
</UserControl>
|
||||||
@ -0,0 +1,83 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Specialized;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Windows.Input;
|
||||||
|
using Artemis.Core;
|
||||||
|
using Artemis.Core.Modules;
|
||||||
|
using Artemis.UI.Ninject.Factories;
|
||||||
|
using Artemis.UI.Shared;
|
||||||
|
using Artemis.UI.Shared.Services;
|
||||||
|
using Stylet;
|
||||||
|
|
||||||
|
namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions.Event
|
||||||
|
{
|
||||||
|
public class EventConditionViewModel : Screen
|
||||||
|
{
|
||||||
|
private readonly INodeVmFactory _nodeVmFactory;
|
||||||
|
private readonly IProfileEditorService _profileEditorService;
|
||||||
|
private readonly IWindowManager _windowManager;
|
||||||
|
|
||||||
|
public EventConditionViewModel(EventCondition eventCondition, IWindowManager windowManager, INodeVmFactory nodeVmFactory, IProfileEditorService profileEditorService)
|
||||||
|
{
|
||||||
|
_windowManager = windowManager;
|
||||||
|
_nodeVmFactory = nodeVmFactory;
|
||||||
|
_profileEditorService = profileEditorService;
|
||||||
|
|
||||||
|
EventCondition = eventCondition;
|
||||||
|
DisplayName = EventCondition.EventPath?.Segments.LastOrDefault()?.GetPropertyDescription()?.Name ?? "Invalid event";
|
||||||
|
FilterTypes = new BindableCollection<Type> {typeof(IDataModelEvent) };
|
||||||
|
Modules = new BindableCollection<Module>();
|
||||||
|
|
||||||
|
if (_profileEditorService.SelectedProfileConfiguration?.Module != null)
|
||||||
|
Modules.Add(_profileEditorService.SelectedProfileConfiguration.Module);
|
||||||
|
}
|
||||||
|
|
||||||
|
public EventCondition EventCondition { get; }
|
||||||
|
public BindableCollection<Type> FilterTypes { get; }
|
||||||
|
public BindableCollection<Module> Modules { get; }
|
||||||
|
public bool CanDeleteEvent => ((EventsConditionViewModel) Parent).Items.Count > 1;
|
||||||
|
|
||||||
|
public void DeleteEvent()
|
||||||
|
{
|
||||||
|
((EventsConditionViewModel) Parent).DeleteEvent(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DataModelPathSelected(object sender, DataModelSelectedEventArgs e)
|
||||||
|
{
|
||||||
|
EventCondition.UpdateEventNode();
|
||||||
|
DisplayName = EventCondition.EventPath?.Segments.LastOrDefault()?.GetPropertyDescription()?.Name ?? "Invalid event";
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ScriptGridMouseUp(object sender, MouseButtonEventArgs e)
|
||||||
|
{
|
||||||
|
if (e.ChangedButton != MouseButton.Left)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_windowManager.ShowDialog(_nodeVmFactory.NodeScriptWindowViewModel(EventCondition.Script));
|
||||||
|
_profileEditorService.SaveSelectedProfileElement();
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Overrides of Screen
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void OnInitialActivate()
|
||||||
|
{
|
||||||
|
((EventsConditionViewModel) Parent).Items.CollectionChanged += ItemsOnCollectionChanged;
|
||||||
|
base.OnInitialActivate();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void OnClose()
|
||||||
|
{
|
||||||
|
((EventsConditionViewModel) Parent).Items.CollectionChanged -= ItemsOnCollectionChanged;
|
||||||
|
base.OnClose();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
private void ItemsOnCollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
|
||||||
|
{
|
||||||
|
NotifyOfPropertyChange(nameof(CanDeleteEvent));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,17 +1,17 @@
|
|||||||
<UserControl x:Class="Artemis.UI.Screens.ProfileEditor.DisplayConditions.DisplayConditionEventView"
|
<UserControl x:Class="Artemis.UI.Screens.ProfileEditor.DisplayConditions.Event.EventsConditionView"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:local="clr-namespace:Artemis.UI.Screens.ProfileEditor.DisplayConditions"
|
xmlns:local="clr-namespace:Artemis.UI.Screens.ProfileEditor.DisplayConditions.Event"
|
||||||
xmlns:core="clr-namespace:Artemis.Core;assembly=Artemis.Core"
|
|
||||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
|
||||||
xmlns:converters="clr-namespace:Artemis.UI.Converters"
|
xmlns:converters="clr-namespace:Artemis.UI.Converters"
|
||||||
xmlns:s="https://github.com/canton7/Stylet"
|
xmlns:s="https://github.com/canton7/Stylet"
|
||||||
xmlns:controls="clr-namespace:Artemis.VisualScripting.Editor.Controls;assembly=Artemis.VisualScripting"
|
xmlns:controls="clr-namespace:Artemis.VisualScripting.Editor.Controls;assembly=Artemis.VisualScripting"
|
||||||
|
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||||
|
xmlns:core="clr-namespace:Artemis.Core;assembly=Artemis.Core"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
d:DesignHeight="450" d:DesignWidth="800"
|
d:DesignHeight="450" d:DesignWidth="800"
|
||||||
d:DataContext="{d:DesignInstance {x:Type local:DisplayConditionEventViewModel}}">
|
d:DataContext="{d:DesignInstance {x:Type local:EventsConditionViewModel}}">
|
||||||
<UserControl.Resources>
|
<UserControl.Resources>
|
||||||
<converters:ComparisonConverter x:Key="ComparisonConverter" />
|
<converters:ComparisonConverter x:Key="ComparisonConverter" />
|
||||||
</UserControl.Resources>
|
</UserControl.Resources>
|
||||||
@ -22,48 +22,37 @@
|
|||||||
<RowDefinition Height="Auto" />
|
<RowDefinition Height="Auto" />
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
<Grid Grid.Row="0" MouseUp="{s:Action ScriptGridMouseUp}" Cursor="Hand">
|
<TabControl Grid.Row="0"
|
||||||
<controls:VisualScriptPresenter Script="{Binding RenderProfileElement.DisplayCondition}"
|
VerticalAlignment="Stretch"
|
||||||
AutoFitScript="True"
|
ItemsSource="{Binding Items}"
|
||||||
Visibility="{Binding RenderProfileElement.DisplayCondition, Converter={StaticResource NullToVisibilityConverter}}" />
|
SelectedItem="{Binding ActiveItem}"
|
||||||
<Border Opacity="0">
|
Style="{StaticResource MaterialDesignTabControl}">
|
||||||
<Border.Background>
|
<TabControl.ItemTemplate>
|
||||||
<SolidColorBrush Color="{Binding Color, Source={StaticResource MaterialDesignCardBackground}}" Opacity="0.75" />
|
<DataTemplate>
|
||||||
</Border.Background>
|
<DockPanel LastChildFill="True" Margin="-15 0">
|
||||||
<Border.Style>
|
<Button DockPanel.Dock="Right"
|
||||||
<Style>
|
Style="{StaticResource MaterialDesignIconForegroundButton}"
|
||||||
<Style.Triggers>
|
Command="{s:Action DeleteEvent}"
|
||||||
<DataTrigger Binding="{Binding IsMouseOver, RelativeSource={RelativeSource AncestorType={x:Type Grid}, Mode=FindAncestor}}" Value="True">
|
s:View.ActionTarget="{Binding}"
|
||||||
<DataTrigger.EnterActions>
|
CommandParameter="{Binding}"
|
||||||
<BeginStoryboard>
|
Width="25"
|
||||||
<Storyboard>
|
Height="25">
|
||||||
<DoubleAnimation Storyboard.TargetProperty="Opacity" To="1" Duration="0:0:0.25" />
|
<materialDesign:PackIcon Kind="Close" Width="15" Height="15" Foreground="{DynamicResource MaterialDesignBody}" />
|
||||||
</Storyboard>
|
</Button>
|
||||||
</BeginStoryboard>
|
<Label Content="{Binding DisplayName}" DockPanel.Dock="Left" />
|
||||||
</DataTrigger.EnterActions>
|
</DockPanel>
|
||||||
<DataTrigger.ExitActions>
|
</DataTemplate>
|
||||||
<BeginStoryboard>
|
</TabControl.ItemTemplate>
|
||||||
<Storyboard>
|
<TabControl.ContentTemplate>
|
||||||
<DoubleAnimation Storyboard.TargetProperty="Opacity" To="0" Duration="0:0:0.25" />
|
<DataTemplate>
|
||||||
</Storyboard>
|
<ContentControl s:View.Model="{Binding IsAsync=True}"
|
||||||
</BeginStoryboard>
|
VerticalContentAlignment="Stretch"
|
||||||
</DataTrigger.ExitActions>
|
HorizontalContentAlignment="Stretch"
|
||||||
</DataTrigger>
|
IsTabStop="False"
|
||||||
</Style.Triggers>
|
TextElement.Foreground="{DynamicResource MaterialDesignBody}" />
|
||||||
</Style>
|
</DataTemplate>
|
||||||
</Border.Style>
|
</TabControl.ContentTemplate>
|
||||||
<Grid HorizontalAlignment="Center">
|
</TabControl>
|
||||||
<Grid.ColumnDefinitions>
|
|
||||||
<ColumnDefinition />
|
|
||||||
<ColumnDefinition />
|
|
||||||
</Grid.ColumnDefinitions>
|
|
||||||
<TextBlock Style="{StaticResource MaterialDesignHeadline5TextBlock}" VerticalAlignment="Center" Grid.Column="0">
|
|
||||||
Click to edit script
|
|
||||||
</TextBlock>
|
|
||||||
<materialDesign:PackIcon Kind="OpenInNew" Margin="10 " Width="30" Height="30" Grid.Column="1" VerticalAlignment="Center" />
|
|
||||||
</Grid>
|
|
||||||
</Border>
|
|
||||||
</Grid>
|
|
||||||
|
|
||||||
<!-- Trigger mode -->
|
<!-- Trigger mode -->
|
||||||
<TextBlock Grid.Row="1" Grid.Column="0" Text="Trigger mode" VerticalAlignment="Center">
|
<TextBlock Grid.Row="1" Grid.Column="0" Text="Trigger mode" VerticalAlignment="Center">
|
||||||
@ -0,0 +1,65 @@
|
|||||||
|
using System.Linq;
|
||||||
|
using Artemis.Core;
|
||||||
|
using Artemis.UI.Ninject.Factories;
|
||||||
|
using Artemis.UI.Shared.Services;
|
||||||
|
using Stylet;
|
||||||
|
|
||||||
|
namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions.Event
|
||||||
|
{
|
||||||
|
public class EventsConditionViewModel : Conductor<EventConditionViewModel>.Collection.OneActive
|
||||||
|
{
|
||||||
|
private readonly IConditionVmFactory _conditionVmFactory;
|
||||||
|
private readonly IProfileEditorService _profileEditorService;
|
||||||
|
|
||||||
|
public EventsConditionViewModel(EventsCondition eventsCondition, IConditionVmFactory conditionVmFactory, IProfileEditorService profileEditorService)
|
||||||
|
{
|
||||||
|
_conditionVmFactory = conditionVmFactory;
|
||||||
|
_profileEditorService = profileEditorService;
|
||||||
|
EventsCondition = eventsCondition;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EventsCondition EventsCondition { get; }
|
||||||
|
|
||||||
|
public TimeLineEventOverlapMode EventOverlapMode
|
||||||
|
{
|
||||||
|
get => EventsCondition.EventOverlapMode;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (EventsCondition.EventOverlapMode == value) return;
|
||||||
|
EventsCondition.EventOverlapMode = value;
|
||||||
|
_profileEditorService.SaveSelectedProfileElement();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddEvent()
|
||||||
|
{
|
||||||
|
EventCondition eventCondition = EventsCondition.AddEventCondition();
|
||||||
|
Items.Add(_conditionVmFactory.EventConditionViewModel(eventCondition));
|
||||||
|
|
||||||
|
_profileEditorService.SaveSelectedProfileElement();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DeleteEvent(EventConditionViewModel eventConditionViewModel)
|
||||||
|
{
|
||||||
|
EventsCondition.RemoveEventCondition(eventConditionViewModel.EventCondition);
|
||||||
|
Items.Remove(eventConditionViewModel);
|
||||||
|
|
||||||
|
_profileEditorService.SaveSelectedProfileElement();
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Overrides of Screen
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void OnInitialActivate()
|
||||||
|
{
|
||||||
|
if (!EventsCondition.Events.Any())
|
||||||
|
EventsCondition.AddEventCondition();
|
||||||
|
|
||||||
|
foreach (EventCondition eventCondition in EventsCondition.Events)
|
||||||
|
Items.Add(_conditionVmFactory.EventConditionViewModel(eventCondition));
|
||||||
|
base.OnInitialActivate();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,181 @@
|
|||||||
|
<UserControl x:Class="Artemis.UI.Screens.ProfileEditor.DisplayConditions.Static.StaticConditionView"
|
||||||
|
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:local="clr-namespace:Artemis.UI.Screens.ProfileEditor.DisplayConditions.Static"
|
||||||
|
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||||
|
xmlns:controls="clr-namespace:Artemis.VisualScripting.Editor.Controls;assembly=Artemis.VisualScripting"
|
||||||
|
xmlns:s="https://github.com/canton7/Stylet"
|
||||||
|
xmlns:converters="clr-namespace:Artemis.UI.Converters"
|
||||||
|
xmlns:shared="clr-namespace:Artemis.UI.Shared;assembly=Artemis.UI.Shared"
|
||||||
|
mc:Ignorable="d"
|
||||||
|
d:DesignHeight="450" d:DesignWidth="800"
|
||||||
|
d:DataContext="{d:DesignInstance {x:Type local:StaticConditionViewModel}}">
|
||||||
|
<UserControl.Resources>
|
||||||
|
<converters:InverseBooleanConverter x:Key="InverseBooleanConverter" />
|
||||||
|
</UserControl.Resources>
|
||||||
|
<Grid>
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="*" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
|
<Grid Grid.Row="0" MouseUp="{s:Action ScriptGridMouseUp}" Cursor="Hand">
|
||||||
|
<controls:VisualScriptPresenter Script="{Binding StaticCondition.Script}" AutoFitScript="True"/>
|
||||||
|
<Border Opacity="0">
|
||||||
|
<Border.Background>
|
||||||
|
<SolidColorBrush Color="{Binding Color, Source={StaticResource MaterialDesignCardBackground}}" Opacity="0.75" />
|
||||||
|
</Border.Background>
|
||||||
|
<Border.Style>
|
||||||
|
<Style>
|
||||||
|
<Style.Triggers>
|
||||||
|
<DataTrigger Binding="{Binding IsMouseOver, RelativeSource={RelativeSource AncestorType={x:Type Grid}, Mode=FindAncestor}}" Value="True">
|
||||||
|
<DataTrigger.EnterActions>
|
||||||
|
<BeginStoryboard>
|
||||||
|
<Storyboard>
|
||||||
|
<DoubleAnimation Storyboard.TargetProperty="Opacity" To="1" Duration="0:0:0.25" />
|
||||||
|
</Storyboard>
|
||||||
|
</BeginStoryboard>
|
||||||
|
</DataTrigger.EnterActions>
|
||||||
|
<DataTrigger.ExitActions>
|
||||||
|
<BeginStoryboard>
|
||||||
|
<Storyboard>
|
||||||
|
<DoubleAnimation Storyboard.TargetProperty="Opacity" To="0" Duration="0:0:0.25" />
|
||||||
|
</Storyboard>
|
||||||
|
</BeginStoryboard>
|
||||||
|
</DataTrigger.ExitActions>
|
||||||
|
</DataTrigger>
|
||||||
|
</Style.Triggers>
|
||||||
|
</Style>
|
||||||
|
</Border.Style>
|
||||||
|
<Grid HorizontalAlignment="Center">
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition />
|
||||||
|
<ColumnDefinition />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<TextBlock Style="{StaticResource MaterialDesignHeadline5TextBlock}" VerticalAlignment="Center" Grid.Column="0">
|
||||||
|
Click to edit script
|
||||||
|
</TextBlock>
|
||||||
|
<materialDesign:PackIcon Kind="OpenInNew" Margin="10 " Width="30" Height="30" Grid.Column="1" VerticalAlignment="Center" />
|
||||||
|
</Grid>
|
||||||
|
</Border>
|
||||||
|
</Grid>
|
||||||
|
<Grid Grid.Row="1">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="22" />
|
||||||
|
<RowDefinition />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="*" MinWidth="140" />
|
||||||
|
<ColumnDefinition Width="*" MinWidth="170" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
|
<!-- Play mode -->
|
||||||
|
<TextBlock Grid.Column="0" Text="Play mode" VerticalAlignment="Center">
|
||||||
|
<TextBlock.ToolTip>
|
||||||
|
<ToolTip Placement="Center" VerticalOffset="-30">
|
||||||
|
<TextBlock>
|
||||||
|
Configure how the layer should act while the conditions above are met
|
||||||
|
</TextBlock>
|
||||||
|
</ToolTip>
|
||||||
|
</TextBlock.ToolTip>
|
||||||
|
</TextBlock>
|
||||||
|
<materialDesign:ColorZone Grid.Row="1" Grid.Column="0" Mode="Standard" CornerRadius="3" Margin="0 0 2 0">
|
||||||
|
<Grid>
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition />
|
||||||
|
<ColumnDefinition />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<RadioButton Grid.Column="0"
|
||||||
|
Style="{StaticResource MaterialDesignTabRadioButton}"
|
||||||
|
IsChecked="{Binding DisplayContinuously}"
|
||||||
|
MinWidth="0"
|
||||||
|
Padding="5 0">
|
||||||
|
<RadioButton.ToolTip>
|
||||||
|
<ToolTip Placement="Center" VerticalOffset="-40">
|
||||||
|
<TextBlock>
|
||||||
|
Continue repeating the main segment of the timeline while the condition is met
|
||||||
|
</TextBlock>
|
||||||
|
</ToolTip>
|
||||||
|
</RadioButton.ToolTip>
|
||||||
|
<TextBlock VerticalAlignment="Center" FontSize="12">
|
||||||
|
<materialDesign:PackIcon Kind="Repeat" VerticalAlignment="Center" Margin="-3 0 0 -3" />
|
||||||
|
REPEAT
|
||||||
|
</TextBlock>
|
||||||
|
</RadioButton>
|
||||||
|
<RadioButton Grid.Column="1"
|
||||||
|
Style="{StaticResource MaterialDesignTabRadioButton}"
|
||||||
|
IsChecked="{Binding DisplayContinuously, Converter={StaticResource InverseBooleanConverter}}"
|
||||||
|
MinWidth="0"
|
||||||
|
Padding="5 0">
|
||||||
|
<RadioButton.ToolTip>
|
||||||
|
<ToolTip Placement="Center" VerticalOffset="-40">
|
||||||
|
<TextBlock>
|
||||||
|
Only play the timeline once when the condition is met
|
||||||
|
</TextBlock>
|
||||||
|
</ToolTip>
|
||||||
|
</RadioButton.ToolTip>
|
||||||
|
<TextBlock VerticalAlignment="Center" FontSize="12">
|
||||||
|
<materialDesign:PackIcon Kind="StopwatchOutline" VerticalAlignment="Center" Margin="-3 0 0 -3" />
|
||||||
|
ONCE
|
||||||
|
</TextBlock>
|
||||||
|
</RadioButton>
|
||||||
|
</Grid>
|
||||||
|
</materialDesign:ColorZone>
|
||||||
|
|
||||||
|
<!-- Stop mode -->
|
||||||
|
<TextBlock Grid.Row="0" Grid.Column="1" Text="Stop mode">
|
||||||
|
<TextBlock.ToolTip>
|
||||||
|
<ToolTip Placement="Center" VerticalOffset="-30">
|
||||||
|
<TextBlock>
|
||||||
|
Configure how the layer should act when the conditions above are no longer met
|
||||||
|
</TextBlock>
|
||||||
|
</ToolTip>
|
||||||
|
</TextBlock.ToolTip>
|
||||||
|
</TextBlock>
|
||||||
|
<materialDesign:ColorZone Grid.Row="1" Grid.Column="1" Mode="Standard" CornerRadius="3" Margin="2 0 0 0" HorizontalAlignment="Stretch">
|
||||||
|
<Grid>
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition />
|
||||||
|
<ColumnDefinition MinWidth="100" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<RadioButton Grid.Column="0"
|
||||||
|
Style="{StaticResource MaterialDesignTabRadioButton}"
|
||||||
|
IsChecked="{Binding AlwaysFinishTimeline}"
|
||||||
|
MinWidth="0"
|
||||||
|
Padding="5 0">
|
||||||
|
<RadioButton.ToolTip>
|
||||||
|
<ToolTip Placement="Center" VerticalOffset="-40">
|
||||||
|
<TextBlock>
|
||||||
|
When conditions are no longer met, finish the the current run of the main timeline
|
||||||
|
</TextBlock>
|
||||||
|
</ToolTip>
|
||||||
|
</RadioButton.ToolTip>
|
||||||
|
<TextBlock VerticalAlignment="Center" FontSize="12">
|
||||||
|
<materialDesign:PackIcon Kind="PlayOutline" VerticalAlignment="Center" Margin="-3 0 0 -3" />
|
||||||
|
FINISH
|
||||||
|
</TextBlock>
|
||||||
|
</RadioButton>
|
||||||
|
<RadioButton Grid.Column="1"
|
||||||
|
Style="{StaticResource MaterialDesignTabRadioButton}"
|
||||||
|
IsChecked="{Binding AlwaysFinishTimeline, Converter={StaticResource InverseBooleanConverter}}"
|
||||||
|
MinWidth="0"
|
||||||
|
Padding="5 0">
|
||||||
|
<RadioButton.ToolTip>
|
||||||
|
<ToolTip Placement="Center" VerticalOffset="-40">
|
||||||
|
<TextBlock>
|
||||||
|
When conditions are no longer met, skip to the end segment of the timeline
|
||||||
|
</TextBlock>
|
||||||
|
</ToolTip>
|
||||||
|
</RadioButton.ToolTip>
|
||||||
|
<TextBlock VerticalAlignment="Center" FontSize="12">
|
||||||
|
<materialDesign:PackIcon Kind="SkipNextOutline" VerticalAlignment="Center" Margin="-3 0 0 -3" />
|
||||||
|
SKIP TO END
|
||||||
|
</TextBlock>
|
||||||
|
</RadioButton>
|
||||||
|
</Grid>
|
||||||
|
</materialDesign:ColorZone>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</UserControl>
|
||||||
@ -0,0 +1,60 @@
|
|||||||
|
using System.Windows.Input;
|
||||||
|
using Artemis.Core;
|
||||||
|
using Artemis.UI.Ninject.Factories;
|
||||||
|
using Artemis.UI.Shared.Services;
|
||||||
|
using Stylet;
|
||||||
|
|
||||||
|
namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions.Static
|
||||||
|
{
|
||||||
|
public class StaticConditionViewModel : Screen
|
||||||
|
{
|
||||||
|
private readonly IWindowManager _windowManager;
|
||||||
|
private readonly INodeVmFactory _nodeVmFactory;
|
||||||
|
private readonly IProfileEditorService _profileEditorService;
|
||||||
|
private readonly RenderProfileElement _renderProfileElement;
|
||||||
|
|
||||||
|
public StaticConditionViewModel(StaticCondition staticCondition, IWindowManager windowManager, INodeVmFactory nodeVmFactory, IProfileEditorService profileEditorService)
|
||||||
|
{
|
||||||
|
_windowManager = windowManager;
|
||||||
|
_nodeVmFactory = nodeVmFactory;
|
||||||
|
_profileEditorService = profileEditorService;
|
||||||
|
_renderProfileElement = (RenderProfileElement) staticCondition.ProfileElement;
|
||||||
|
StaticCondition = staticCondition;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StaticCondition StaticCondition { get; }
|
||||||
|
|
||||||
|
public bool DisplayContinuously
|
||||||
|
{
|
||||||
|
get => _renderProfileElement.Timeline.PlayMode == TimelinePlayMode.Repeat;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
TimelinePlayMode playMode = value ? TimelinePlayMode.Repeat : TimelinePlayMode.Once;
|
||||||
|
if (_renderProfileElement.Timeline.PlayMode == playMode) return;
|
||||||
|
_renderProfileElement.Timeline.PlayMode = playMode;
|
||||||
|
_profileEditorService.SaveSelectedProfileElement();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool AlwaysFinishTimeline
|
||||||
|
{
|
||||||
|
get => _renderProfileElement?.Timeline.StopMode == TimelineStopMode.Finish;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
TimelineStopMode stopMode = value ? TimelineStopMode.Finish : TimelineStopMode.SkipToEnd;
|
||||||
|
if (_renderProfileElement.Timeline.StopMode == stopMode) return;
|
||||||
|
_renderProfileElement.Timeline.StopMode = stopMode;
|
||||||
|
_profileEditorService.SaveSelectedProfileElement();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ScriptGridMouseUp(object sender, MouseButtonEventArgs e)
|
||||||
|
{
|
||||||
|
if (e.ChangedButton != MouseButton.Left)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_windowManager.ShowDialog(_nodeVmFactory.NodeScriptWindowViewModel(StaticCondition.Script));
|
||||||
|
_profileEditorService.SaveSelectedProfileElement();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -282,7 +282,7 @@ namespace Artemis.VisualScripting.Editor.Controls.Wrapper
|
|||||||
Script.RemoveNode(this);
|
Script.RemoveNode(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool RemoveCanExecute() => !Node.IsExitNode;
|
private bool RemoveCanExecute() => !Node.IsExitNode && !Node.IsDefaultNode;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user