mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-13 05:48:35 +00:00
Profile editor - Fixed new profile elements not always appearing
UI - Fixed all the memory leaks I could find, closing the UI now frees a lot of RAM Noise brush - Decreased memory usage by removing unused 4D noise Layout editor - Fixed device properties not always applying
This commit is contained in:
parent
8cd9c8a5f8
commit
dab11cb3e7
@ -146,6 +146,8 @@ namespace Artemis.Core.Models.Profile
|
||||
|
||||
child.Parent = this;
|
||||
}
|
||||
|
||||
OnChildAdded();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -164,6 +166,8 @@ namespace Artemis.Core.Models.Profile
|
||||
|
||||
child.Parent = null;
|
||||
}
|
||||
|
||||
OnChildRemoved();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
@ -175,5 +179,22 @@ namespace Artemis.Core.Models.Profile
|
||||
/// Applies the profile element's properties to the underlying storage entity
|
||||
/// </summary>
|
||||
internal abstract void ApplyToEntity();
|
||||
|
||||
#region Events
|
||||
|
||||
public event EventHandler ChildAdded;
|
||||
public event EventHandler ChildRemoved;
|
||||
|
||||
protected virtual void OnChildAdded()
|
||||
{
|
||||
ChildAdded?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
protected virtual void OnChildRemoved()
|
||||
{
|
||||
ChildRemoved?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@ -3,15 +3,12 @@ using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Threading;
|
||||
using Artemis.Core.Models.Surface;
|
||||
using RGB.NET.Core;
|
||||
using Size = System.Windows.Size;
|
||||
|
||||
namespace Artemis.UI.Shared.Controls
|
||||
{
|
||||
@ -28,9 +25,9 @@ namespace Artemis.UI.Shared.Controls
|
||||
|
||||
private readonly DrawingGroup _backingStore;
|
||||
private readonly List<DeviceVisualizerLed> _deviceVisualizerLeds;
|
||||
private readonly DispatcherTimer _timer;
|
||||
private BitmapImage _deviceImage;
|
||||
private ArtemisDevice _oldDevice;
|
||||
private readonly DispatcherTimer _timer;
|
||||
|
||||
public DeviceVisualizer()
|
||||
{
|
||||
@ -41,8 +38,8 @@ namespace Artemis.UI.Shared.Controls
|
||||
_timer = new DispatcherTimer {Interval = TimeSpan.FromMilliseconds(40)};
|
||||
_timer.Tick += TimerOnTick;
|
||||
|
||||
Loaded += (sender, args) => _timer.Start();
|
||||
Unloaded += (sender, args) => _timer.Stop();
|
||||
Loaded += OnLoaded;
|
||||
Unloaded += OnUnloaded;
|
||||
}
|
||||
|
||||
public ArtemisDevice Device
|
||||
@ -117,12 +114,28 @@ namespace Artemis.UI.Shared.Controls
|
||||
return rotationRect.Size;
|
||||
}
|
||||
|
||||
private void OnUnloaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
_timer.Stop();
|
||||
|
||||
if (_oldDevice != null)
|
||||
{
|
||||
Device.RgbDevice.PropertyChanged -= DevicePropertyChanged;
|
||||
_oldDevice = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnLoaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
_timer.Start();
|
||||
}
|
||||
|
||||
private void TimerOnTick(object sender, EventArgs e)
|
||||
{
|
||||
if (ShowColors && Visibility == Visibility.Visible)
|
||||
Render();
|
||||
}
|
||||
|
||||
|
||||
private void UpdateTransform()
|
||||
{
|
||||
InvalidateVisual();
|
||||
@ -204,7 +217,7 @@ namespace Artemis.UI.Shared.Controls
|
||||
if (e.PropertyName == nameof(Device.RgbDevice.Scale) || e.PropertyName == nameof(Device.RgbDevice.Rotation))
|
||||
UpdateTransform();
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void Render()
|
||||
{
|
||||
|
||||
@ -23,8 +23,9 @@ namespace Artemis.UI.Shared.Services
|
||||
private readonly ILogger _logger;
|
||||
private readonly List<PropertyInputRegistration> _registeredPropertyEditors;
|
||||
private TimeSpan _currentTime;
|
||||
private TimeSpan _lastUpdateTime;
|
||||
private int _pixelsPerSecond;
|
||||
private object _selectedProfileLock = new object();
|
||||
private object _selectedProfileElementLock = new object();
|
||||
|
||||
public ProfileEditorService(ICoreService coreService, IProfileService profileService, IKernel kernel, ILogger logger)
|
||||
{
|
||||
@ -69,43 +70,55 @@ namespace Artemis.UI.Shared.Services
|
||||
|
||||
public void ChangeSelectedProfile(Profile profile)
|
||||
{
|
||||
if (SelectedProfile == profile)
|
||||
return;
|
||||
lock (_selectedProfileLock)
|
||||
{
|
||||
if (SelectedProfile == profile)
|
||||
return;
|
||||
|
||||
_logger.Verbose("ChangeSelectedProfile {profile}", profile);
|
||||
ChangeSelectedProfileElement(null);
|
||||
_logger.Verbose("ChangeSelectedProfile {profile}", profile);
|
||||
ChangeSelectedProfileElement(null);
|
||||
|
||||
var profileElementEvent = new ProfileEventArgs(profile, SelectedProfile);
|
||||
SelectedProfile = profile;
|
||||
UpdateProfilePreview();
|
||||
OnSelectedProfileChanged(profileElementEvent);
|
||||
var profileElementEvent = new ProfileEventArgs(profile, SelectedProfile);
|
||||
SelectedProfile = profile;
|
||||
UpdateProfilePreview();
|
||||
OnSelectedProfileChanged(profileElementEvent);
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateSelectedProfile()
|
||||
{
|
||||
_logger.Verbose("UpdateSelectedProfile {profile}", SelectedProfile);
|
||||
_profileService.UpdateProfile(SelectedProfile, true);
|
||||
UpdateProfilePreview();
|
||||
OnSelectedProfileChanged(new ProfileEventArgs(SelectedProfile));
|
||||
lock (_selectedProfileLock)
|
||||
{
|
||||
_logger.Verbose("UpdateSelectedProfile {profile}", SelectedProfile);
|
||||
_profileService.UpdateProfile(SelectedProfile, true);
|
||||
UpdateProfilePreview();
|
||||
OnSelectedProfileChanged(new ProfileEventArgs(SelectedProfile));
|
||||
}
|
||||
}
|
||||
|
||||
public void ChangeSelectedProfileElement(RenderProfileElement profileElement)
|
||||
{
|
||||
if (SelectedProfileElement == profileElement)
|
||||
return;
|
||||
lock (_selectedProfileElementLock)
|
||||
{
|
||||
if (SelectedProfileElement == profileElement)
|
||||
return;
|
||||
|
||||
_logger.Verbose("ChangeSelectedProfileElement {profile}", profileElement);
|
||||
var profileElementEvent = new RenderProfileElementEventArgs(profileElement, SelectedProfileElement);
|
||||
SelectedProfileElement = profileElement;
|
||||
OnSelectedProfileElementChanged(profileElementEvent);
|
||||
_logger.Verbose("ChangeSelectedProfileElement {profile}", profileElement);
|
||||
var profileElementEvent = new RenderProfileElementEventArgs(profileElement, SelectedProfileElement);
|
||||
SelectedProfileElement = profileElement;
|
||||
OnSelectedProfileElementChanged(profileElementEvent);
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateSelectedProfileElement()
|
||||
{
|
||||
_logger.Verbose("UpdateSelectedProfileElement {profile}", SelectedProfileElement);
|
||||
_profileService.UpdateProfile(SelectedProfile, true);
|
||||
UpdateProfilePreview();
|
||||
OnSelectedProfileElementUpdated(new RenderProfileElementEventArgs(SelectedProfileElement));
|
||||
lock (_selectedProfileElementLock)
|
||||
{
|
||||
_logger.Verbose("UpdateSelectedProfileElement {profile}", SelectedProfileElement);
|
||||
_profileService.UpdateProfile(SelectedProfile, true);
|
||||
UpdateProfilePreview();
|
||||
OnSelectedProfileElementUpdated(new RenderProfileElementEventArgs(SelectedProfileElement));
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateProfilePreview()
|
||||
@ -114,12 +127,11 @@ namespace Artemis.UI.Shared.Services
|
||||
return;
|
||||
|
||||
// Stick to the main segment for any element that is not currently selected
|
||||
foreach (var folder in SelectedProfile.GetAllFolders())
|
||||
foreach (var folder in SelectedProfile.GetAllFolders())
|
||||
folder.OverrideProgress(CurrentTime, folder != SelectedProfileElement);
|
||||
foreach (var layer in SelectedProfile.GetAllLayers())
|
||||
foreach (var layer in SelectedProfile.GetAllLayers())
|
||||
layer.OverrideProgress(CurrentTime, layer != SelectedProfileElement);
|
||||
|
||||
_lastUpdateTime = CurrentTime;
|
||||
OnProfilePreviewUpdated();
|
||||
}
|
||||
|
||||
@ -225,7 +237,7 @@ namespace Artemis.UI.Shared.Services
|
||||
{
|
||||
// Get all visible keyframes
|
||||
var keyframes = SelectedProfileElement.GetAllKeyframes()
|
||||
.Where(k => SelectedProfileElement.IsPropertyGroupExpanded(k.BaseLayerProperty.Parent))
|
||||
.Where(k => k != excludedKeyframe && SelectedProfileElement.IsPropertyGroupExpanded(k.BaseLayerProperty.Parent))
|
||||
.ToList();
|
||||
|
||||
// Find the closest keyframe
|
||||
|
||||
@ -9,8 +9,7 @@ namespace Artemis.UI.Converters
|
||||
{
|
||||
#region IValueConverter Members
|
||||
|
||||
public object Convert(object value, Type targetType, object parameter,
|
||||
CultureInfo culture)
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
if (targetType == typeof(bool))
|
||||
return !(bool) value;
|
||||
@ -20,10 +19,14 @@ namespace Artemis.UI.Converters
|
||||
throw new InvalidOperationException("The target must be a boolean");
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter,
|
||||
CultureInfo culture)
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
if (targetType == typeof(bool))
|
||||
return !(bool) value;
|
||||
if (targetType == typeof(bool?))
|
||||
return !(bool?) value;
|
||||
|
||||
throw new InvalidOperationException("The target must be a boolean");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@ -4,6 +4,7 @@ using Artemis.Core.Models.Profile.LayerProperties;
|
||||
using Artemis.UI.Shared.PropertyInput;
|
||||
using Artemis.UI.Shared.Services.Interfaces;
|
||||
using Artemis.UI.Shared.Utilities;
|
||||
using Stylet;
|
||||
|
||||
namespace Artemis.UI.PropertyInput
|
||||
{
|
||||
@ -11,9 +12,9 @@ namespace Artemis.UI.PropertyInput
|
||||
{
|
||||
public EnumPropertyInputViewModel(LayerProperty<T> layerProperty, IProfileEditorService profileEditorService) : base(layerProperty, profileEditorService)
|
||||
{
|
||||
EnumValues = EnumUtilities.GetAllValuesAndDescriptions(typeof(T));
|
||||
EnumValues = new BindableCollection<ValueDescription>(EnumUtilities.GetAllValuesAndDescriptions(typeof(T)));
|
||||
}
|
||||
|
||||
public IEnumerable<ValueDescription> EnumValues { get; }
|
||||
public BindableCollection<ValueDescription> EnumValues { get; }
|
||||
}
|
||||
}
|
||||
@ -13,30 +13,11 @@
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="pack://application:,,,/Artemis.UI;component/ResourceDictionaries/DisplayConditions.xaml" />
|
||||
<ResourceDictionary>
|
||||
<Style TargetType="Grid" x:Key="InitializingFade">
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding IsInitialized}" Value="True">
|
||||
<DataTrigger.EnterActions>
|
||||
<BeginStoryboard>
|
||||
<Storyboard>
|
||||
<DoubleAnimation Storyboard.TargetProperty="Opacity" From="0.0" To="1.0" Duration="0:0:0.25" BeginTime="0:0:0.1">
|
||||
<DoubleAnimation.EasingFunction>
|
||||
<QuadraticEase EasingMode="EaseInOut" />
|
||||
</DoubleAnimation.EasingFunction>
|
||||
</DoubleAnimation>
|
||||
</Storyboard>
|
||||
</BeginStoryboard>
|
||||
</DataTrigger.EnterActions>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</ResourceDictionary>
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
</ResourceDictionary>
|
||||
</UserControl.Resources>
|
||||
|
||||
<Grid Style="{StaticResource InitializingFade}" Opacity="0">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
@ -127,7 +108,13 @@
|
||||
<ItemsControl Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="2" ItemsSource="{Binding Children}">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<ContentControl s:View.Model="{Binding}" VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch" IsTabStop="False" />
|
||||
<materialDesign:TransitioningContent>
|
||||
<materialDesign:TransitioningContent.OpeningEffects>
|
||||
<materialDesign:TransitionEffect Kind="FadeIn" />
|
||||
<materialDesign:TransitionEffect Kind="SlideInFromLeft" />
|
||||
</materialDesign:TransitioningContent.OpeningEffects>
|
||||
<ContentControl s:View.Model="{Binding}" VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch" IsTabStop="False" />
|
||||
</materialDesign:TransitioningContent>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
|
||||
@ -70,7 +70,9 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.DisplayConditions
|
||||
|
||||
// Remove VMs of effects no longer applied on the layer
|
||||
var toRemove = Children.Where(c => !DisplayConditionGroup.Children.Contains(c.Model)).ToList();
|
||||
Children.RemoveRange(toRemove);
|
||||
// Using RemoveRange breaks our lovely animations
|
||||
foreach (var displayConditionViewModel in toRemove)
|
||||
Children.Remove(displayConditionViewModel);
|
||||
|
||||
foreach (var childModel in Model.Children)
|
||||
{
|
||||
|
||||
@ -20,28 +20,11 @@
|
||||
<ResourceDictionary>
|
||||
<converters:NullToVisibilityConverter x:Key="NullToVisibilityConverter" />
|
||||
<utilities:BindingProxy x:Key="DataContextProxy" Data="{Binding}" />
|
||||
<Style TargetType="Grid" x:Key="InitializingFade">
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding IsInitialized}" Value="True">
|
||||
<DataTrigger.EnterActions>
|
||||
<BeginStoryboard>
|
||||
<Storyboard>
|
||||
<DoubleAnimation Storyboard.TargetProperty="Opacity" From="0.0" To="1.0" Duration="0:0:0.25" BeginTime="0:0:0.1">
|
||||
<DoubleAnimation.EasingFunction>
|
||||
<QuadraticEase EasingMode="EaseInOut" />
|
||||
</DoubleAnimation.EasingFunction>
|
||||
</DoubleAnimation>
|
||||
</Storyboard>
|
||||
</BeginStoryboard>
|
||||
</DataTrigger.EnterActions>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</ResourceDictionary>
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
</ResourceDictionary>
|
||||
</UserControl.Resources>
|
||||
<Grid Margin="0 3" Style="{StaticResource InitializingFade}" Opacity="0">
|
||||
<Grid Margin="0 3" Visibility="{Binding IsInitialized, Converter={x:Static s:BoolToVisibilityConverter.Instance}, Mode=OneWay}">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
|
||||
@ -171,13 +171,13 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.DisplayConditions
|
||||
LeftSideDataModel.UpdateRequested += LeftDataModelUpdateRequested;
|
||||
RightSideDataModel.UpdateRequested += RightDataModelUpdateRequested;
|
||||
|
||||
IsInitialized = true;
|
||||
Update();
|
||||
IsInitialized = true;
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
if (!IsInitialized)
|
||||
if (LeftSideDataModel == null || (DisplayConditionPredicate.PredicateType == PredicateType.Dynamic && RightSideDataModel == null))
|
||||
return;
|
||||
|
||||
// If static, only allow selecting properties also supported by input
|
||||
|
||||
@ -6,10 +6,14 @@
|
||||
xmlns:local="clr-namespace:Artemis.UI.Screens.Module.ProfileEditor.DisplayConditions"
|
||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||
xmlns:s="https://github.com/canton7/Stylet"
|
||||
xmlns:converters="clr-namespace:Artemis.UI.Converters"
|
||||
x:Class="Artemis.UI.Screens.Module.ProfileEditor.DisplayConditions.DisplayConditionsView"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800"
|
||||
d:DataContext="{d:DesignInstance {x:Type local:DisplayConditionsViewModel}}">
|
||||
<UserControl.Resources>
|
||||
<converters:InverseBooleanConverter x:Key="InverseBooleanConverter" />
|
||||
</UserControl.Resources>
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
@ -29,10 +33,13 @@
|
||||
</Grid>
|
||||
|
||||
<StackPanel Grid.Row="3" Margin="10" HorizontalAlignment="Right" Orientation="Horizontal">
|
||||
<TextBlock VerticalAlignment="Center" Margin="0 0 10 0">When conditions no longer met</TextBlock>
|
||||
<ListBox Style="{StaticResource MaterialDesignToolToggleListBox}" SelectedIndex="{Binding ConditionBehaviourIndex}" IsEnabled="{Binding ConditionBehaviourEnabled}" Height="22">
|
||||
<ListBoxItem Padding="10 0">
|
||||
<ListBoxItem.ToolTip>
|
||||
<TextBlock VerticalAlignment="Center" Margin="0 0 5 0">On end: </TextBlock>
|
||||
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<RadioButton Style="{StaticResource MaterialDesignTabRadioButton}"
|
||||
IsChecked="{Binding RenderProfileElement.AlwaysFinishTimeline}"
|
||||
Padding="5 0">
|
||||
<RadioButton.ToolTip>
|
||||
<ToolTip Placement="Top" VerticalOffset="-5">
|
||||
<StackPanel>
|
||||
<TextBlock>
|
||||
@ -40,16 +47,18 @@
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
</ToolTip>
|
||||
</ListBoxItem.ToolTip>
|
||||
</RadioButton.ToolTip>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<materialDesign:PackIcon Kind="PlayArrow" Width="20" Height="20" Margin="0 -4" />
|
||||
<TextBlock Margin="5 0 0 0" FontSize="11">
|
||||
<materialDesign:PackIcon Kind="PlayArrow" Width="20" Height="20" VerticalAlignment="Center" />
|
||||
<TextBlock Margin="5 0 0 0" FontSize="12" VerticalAlignment="Center">
|
||||
WAIT FOR FINISH
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
</ListBoxItem>
|
||||
<ListBoxItem Padding="10 0">
|
||||
<ListBoxItem.ToolTip>
|
||||
</RadioButton>
|
||||
<RadioButton Style="{StaticResource MaterialDesignTabRadioButton}"
|
||||
IsChecked="{Binding RenderProfileElement.AlwaysFinishTimeline, Converter={StaticResource InverseBooleanConverter}}"
|
||||
Padding="0">
|
||||
<RadioButton.ToolTip>
|
||||
<ToolTip Placement="Top" VerticalOffset="-5">
|
||||
<StackPanel>
|
||||
<TextBlock>
|
||||
@ -57,15 +66,15 @@
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
</ToolTip>
|
||||
</ListBoxItem.ToolTip>
|
||||
</RadioButton.ToolTip>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<materialDesign:PackIcon Kind="SkipNext" Width="20" Height="20" Margin="0 -4" />
|
||||
<TextBlock Margin="5 0 0 0" FontSize="11">
|
||||
<materialDesign:PackIcon Kind="SkipNext" Width="20" Height="20" VerticalAlignment="Center" Margin="-5 0 0 0"/>
|
||||
<TextBlock Margin="5 0 0 0" FontSize="12" VerticalAlignment="Center">
|
||||
SKIP
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
</ListBoxItem>
|
||||
</ListBox>
|
||||
</RadioButton>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@ -1,9 +1,11 @@
|
||||
using Artemis.Core.Models.Profile;
|
||||
using System.Threading.Tasks;
|
||||
using Artemis.Core.Models.Profile;
|
||||
using Artemis.Core.Models.Profile.Conditions;
|
||||
using Artemis.Storage.Entities.Profile.Abstract;
|
||||
using Artemis.UI.Ninject.Factories;
|
||||
using Artemis.UI.Shared.Events;
|
||||
using Artemis.UI.Shared.Services.Interfaces;
|
||||
using Stylet;
|
||||
|
||||
namespace Artemis.UI.Screens.Module.ProfileEditor.DisplayConditions
|
||||
{
|
||||
@ -18,7 +20,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.DisplayConditions
|
||||
{
|
||||
_profileEditorService = profileEditorService;
|
||||
_displayConditionsVmFactory = displayConditionsVmFactory;
|
||||
profileEditorService.ProfileElementSelected += ProfileEditorServiceOnProfileElementSelected;
|
||||
|
||||
}
|
||||
|
||||
public DisplayConditionGroupViewModel RootGroup
|
||||
@ -42,8 +44,6 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.DisplayConditions
|
||||
return;
|
||||
|
||||
RenderProfileElement.AlwaysFinishTimeline = value == 0;
|
||||
NotifyOfPropertyChange(nameof(ConditionBehaviourIndex));
|
||||
|
||||
_profileEditorService.UpdateSelectedProfileElement();
|
||||
}
|
||||
}
|
||||
@ -70,5 +70,15 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.DisplayConditions
|
||||
RootGroup.IsRootGroup = true;
|
||||
RootGroup.Update();
|
||||
}
|
||||
|
||||
protected override void OnActivate()
|
||||
{
|
||||
_profileEditorService.ProfileElementSelected += ProfileEditorServiceOnProfileElementSelected;
|
||||
}
|
||||
|
||||
protected override void OnDeactivate()
|
||||
{
|
||||
_profileEditorService.ProfileElementSelected -= ProfileEditorServiceOnProfileElementSelected;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -8,11 +8,11 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Abstract
|
||||
public abstract class LayerPropertyBaseViewModel : PropertyChangedBase, IDisposable
|
||||
{
|
||||
private bool _isExpanded;
|
||||
private List<LayerPropertyBaseViewModel> _children;
|
||||
private BindableCollection<LayerPropertyBaseViewModel> _children;
|
||||
|
||||
protected LayerPropertyBaseViewModel()
|
||||
{
|
||||
Children = new List<LayerPropertyBaseViewModel>();
|
||||
Children = new BindableCollection<LayerPropertyBaseViewModel>();
|
||||
}
|
||||
|
||||
public abstract bool IsVisible { get; }
|
||||
@ -23,7 +23,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Abstract
|
||||
set => SetAndNotify(ref _isExpanded, value);
|
||||
}
|
||||
|
||||
public List<LayerPropertyBaseViewModel> Children
|
||||
public BindableCollection<LayerPropertyBaseViewModel> Children
|
||||
{
|
||||
get => _children;
|
||||
set => SetAndNotify(ref _children, value);
|
||||
|
||||
@ -164,6 +164,16 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties
|
||||
ProfileEditorService.PixelsPerSecondChanged -= ProfileEditorServiceOnPixelsPerSecondChanged;
|
||||
|
||||
PopulateProperties(null);
|
||||
|
||||
TimelineViewModel?.Dispose();
|
||||
TimelineViewModel = null;
|
||||
StartTimelineSegmentViewModel?.Dispose();
|
||||
StartTimelineSegmentViewModel = null;
|
||||
MainTimelineSegmentViewModel?.Dispose();
|
||||
MainTimelineSegmentViewModel = null;
|
||||
EndTimelineSegmentViewModel?.Dispose();
|
||||
EndTimelineSegmentViewModel = null;
|
||||
|
||||
base.OnClose();
|
||||
}
|
||||
|
||||
@ -256,9 +266,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties
|
||||
ApplyLayerBrush();
|
||||
ApplyEffects();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private void SelectedLayerOnLayerBrushUpdated(object sender, EventArgs e)
|
||||
{
|
||||
ApplyLayerBrush();
|
||||
|
||||
@ -31,6 +31,18 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
|
||||
LayerPropertyKeyframe.EasingFunction,
|
||||
LayerPropertyKeyframe.LayerProperty
|
||||
);
|
||||
// If possible, shift the keyframe to the right by 11 pixels
|
||||
var desiredPosition = newKeyframe.Position + TimeSpan.FromMilliseconds(1000f / _profileEditorService.PixelsPerSecond * 11);
|
||||
if (desiredPosition <= newKeyframe.LayerProperty.ProfileElement.TimelineLength)
|
||||
newKeyframe.Position = desiredPosition;
|
||||
// Otherwise if possible shift it to the left by 11 pixels
|
||||
else
|
||||
{
|
||||
desiredPosition = newKeyframe.Position - TimeSpan.FromMilliseconds(1000f / _profileEditorService.PixelsPerSecond * 11);
|
||||
if (desiredPosition > TimeSpan.Zero)
|
||||
newKeyframe.Position = desiredPosition;
|
||||
}
|
||||
|
||||
LayerPropertyKeyframe.LayerProperty.AddKeyframe(newKeyframe);
|
||||
_profileEditorService.UpdateSelectedProfileElement();
|
||||
}
|
||||
|
||||
@ -140,14 +140,14 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
|
||||
if (Segment == SegmentViewModelType.Start)
|
||||
{
|
||||
// Remove keyframes that fall in this segment
|
||||
foreach (var baseLayerPropertyKeyframe in keyframes.Where(k => k.Position < startSegmentEnd))
|
||||
foreach (var baseLayerPropertyKeyframe in keyframes.Where(k => k.Position <= startSegmentEnd))
|
||||
baseLayerPropertyKeyframe.Remove();
|
||||
SelectedProfileElement.StartSegmentLength = TimeSpan.Zero;
|
||||
}
|
||||
else if (Segment == SegmentViewModelType.Main)
|
||||
{
|
||||
// Remove keyframes that fall in this segment
|
||||
foreach (var baseLayerPropertyKeyframe in keyframes.Where(k => k.Position > startSegmentEnd && k.Position < mainSegmentEnd))
|
||||
foreach (var baseLayerPropertyKeyframe in keyframes.Where(k => k.Position > startSegmentEnd && k.Position <= mainSegmentEnd))
|
||||
baseLayerPropertyKeyframe.Remove();
|
||||
SelectedProfileElement.MainSegmentLength = TimeSpan.Zero;
|
||||
}
|
||||
@ -189,7 +189,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
|
||||
else if (Segment == SegmentViewModelType.End)
|
||||
segmentEnd = SelectedProfileElement.TimelineLength;
|
||||
|
||||
foreach (var baseLayerPropertyKeyframe in SelectedProfileElement.GetAllKeyframes().Where(k => k.Position >= segmentEnd))
|
||||
foreach (var baseLayerPropertyKeyframe in SelectedProfileElement.GetAllKeyframes().Where(k => k.Position > segmentEnd))
|
||||
baseLayerPropertyKeyframe.Position += amount;
|
||||
}
|
||||
|
||||
|
||||
@ -7,6 +7,7 @@ using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Shapes;
|
||||
using Artemis.Core.Models.Profile;
|
||||
using Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Abstract;
|
||||
using Artemis.UI.Shared.Services.Interfaces;
|
||||
using Artemis.UI.Shared.Utilities;
|
||||
@ -27,13 +28,16 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
|
||||
|
||||
LayerPropertyGroups = layerPropertyGroups;
|
||||
SelectionRectangle = new RectangleGeometry();
|
||||
SelectedProfileElement = layerPropertiesViewModel.SelectedProfileElement;
|
||||
|
||||
_profileEditorService.SelectedProfileElement.PropertyChanged += SelectedProfileElementOnPropertyChanged;
|
||||
SelectedProfileElement.PropertyChanged += SelectedProfileElementOnPropertyChanged;
|
||||
_profileEditorService.PixelsPerSecondChanged += ProfileEditorServiceOnPixelsPerSecondChanged;
|
||||
|
||||
Update();
|
||||
}
|
||||
|
||||
public RenderProfileElement SelectedProfileElement { get; set; }
|
||||
|
||||
public BindableCollection<LayerPropertyGroupViewModel> LayerPropertyGroups { get; }
|
||||
|
||||
public RectangleGeometry SelectionRectangle
|
||||
@ -42,21 +46,21 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
|
||||
set => SetAndNotify(ref _selectionRectangle, value);
|
||||
}
|
||||
|
||||
public double StartSegmentWidth => _profileEditorService.PixelsPerSecond * _profileEditorService.SelectedProfileElement?.StartSegmentLength.TotalSeconds ?? 0;
|
||||
public double StartSegmentWidth => _profileEditorService.PixelsPerSecond * SelectedProfileElement.StartSegmentLength.TotalSeconds;
|
||||
public double StartSegmentEndPosition => StartSegmentWidth;
|
||||
public double MainSegmentWidth => _profileEditorService.PixelsPerSecond * _profileEditorService.SelectedProfileElement?.MainSegmentLength.TotalSeconds ?? 0;
|
||||
public double MainSegmentWidth => _profileEditorService.PixelsPerSecond * SelectedProfileElement.MainSegmentLength.TotalSeconds;
|
||||
public double MainSegmentEndPosition => StartSegmentWidth + MainSegmentWidth;
|
||||
public double EndSegmentWidth => _profileEditorService.PixelsPerSecond * _profileEditorService.SelectedProfileElement?.EndSegmentLength.TotalSeconds ?? 0;
|
||||
public double EndSegmentWidth => _profileEditorService.PixelsPerSecond * SelectedProfileElement.EndSegmentLength.TotalSeconds;
|
||||
public double EndSegmentEndPosition => StartSegmentWidth + MainSegmentWidth + EndSegmentWidth;
|
||||
public double TotalTimelineWidth => _profileEditorService.PixelsPerSecond * _profileEditorService.SelectedProfileElement?.TimelineLength.TotalSeconds ?? 0;
|
||||
public double TotalTimelineWidth => _profileEditorService.PixelsPerSecond * SelectedProfileElement.TimelineLength.TotalSeconds;
|
||||
|
||||
public bool StartSegmentEnabled => _profileEditorService.SelectedProfileElement?.StartSegmentLength != TimeSpan.Zero;
|
||||
public bool EndSegmentEnabled => _profileEditorService.SelectedProfileElement?.EndSegmentLength != TimeSpan.Zero;
|
||||
public bool StartSegmentEnabled => SelectedProfileElement.StartSegmentLength != TimeSpan.Zero;
|
||||
public bool EndSegmentEnabled => SelectedProfileElement.EndSegmentLength != TimeSpan.Zero;
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_profileEditorService.PixelsPerSecondChanged -= ProfileEditorServiceOnPixelsPerSecondChanged;
|
||||
_profileEditorService.SelectedProfileElement.PropertyChanged -= SelectedProfileElementOnPropertyChanged;
|
||||
SelectedProfileElement.PropertyChanged -= SelectedProfileElementOnPropertyChanged;
|
||||
}
|
||||
|
||||
private void SelectedProfileElementOnPropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||
@ -115,8 +119,8 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
|
||||
|
||||
public void KeyframeMouseDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (e.LeftButton == MouseButtonState.Released)
|
||||
return;
|
||||
// if (e.LeftButton == MouseButtonState.Released)
|
||||
// return;
|
||||
|
||||
var viewModel = (sender as Ellipse)?.DataContext as TimelineKeyframeViewModel;
|
||||
if (viewModel == null)
|
||||
@ -220,6 +224,18 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline
|
||||
foreach (var keyframeViewModel in keyframeViewModels.Where(k => k.IsSelected))
|
||||
keyframeViewModel.SaveOffsetToKeyframe(sourceKeyframeViewModel);
|
||||
|
||||
if (Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift))
|
||||
{
|
||||
cursorTime = _profileEditorService.SnapToTimeline(
|
||||
cursorTime,
|
||||
TimeSpan.FromMilliseconds(1000f / _profileEditorService.PixelsPerSecond * 5),
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
sourceKeyframeViewModel.BaseLayerPropertyKeyframe
|
||||
);
|
||||
}
|
||||
|
||||
sourceKeyframeViewModel.UpdatePosition(cursorTime);
|
||||
|
||||
foreach (var keyframeViewModel in keyframeViewModels.Where(k => k.IsSelected))
|
||||
|
||||
@ -5,6 +5,7 @@ using System.Windows;
|
||||
using Artemis.Core.Models.Profile;
|
||||
using Artemis.UI.Ninject.Factories;
|
||||
using Artemis.UI.Screens.Module.ProfileEditor.ProfileTree.TreeItem;
|
||||
using Artemis.UI.Shared.Events;
|
||||
using Artemis.UI.Shared.Services.Interfaces;
|
||||
using GongSolutions.Wpf.DragDrop;
|
||||
using Stylet;
|
||||
@ -109,6 +110,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileTree
|
||||
return;
|
||||
}
|
||||
|
||||
RootFolder?.Dispose();
|
||||
RootFolder = _folderVmFactory.Create(folder);
|
||||
_updatingTree = false;
|
||||
|
||||
@ -168,9 +170,9 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileTree
|
||||
|
||||
#region Event handlers
|
||||
|
||||
private void OnProfileElementSelected(object sender, EventArgs e)
|
||||
private void OnProfileElementSelected(object sender, RenderProfileElementEventArgs e)
|
||||
{
|
||||
if (_profileEditorService.SelectedProfileElement == SelectedTreeItem?.ProfileElement)
|
||||
if (e.RenderProfileElement == SelectedTreeItem?.ProfileElement)
|
||||
return;
|
||||
|
||||
if (RootFolder == null)
|
||||
@ -182,13 +184,13 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileTree
|
||||
_updatingTree = true;
|
||||
RootFolder.UpdateProfileElements();
|
||||
_updatingTree = false;
|
||||
if (_profileEditorService.SelectedProfileElement == null)
|
||||
if (e.RenderProfileElement == null)
|
||||
SelectedTreeItem = null;
|
||||
else
|
||||
{
|
||||
var vms = RootFolder.GetAllChildren();
|
||||
vms.Add(RootFolder);
|
||||
SelectedTreeItem = vms.FirstOrDefault(vm => vm.ProfileElement == _profileEditorService.SelectedProfileElement);
|
||||
var match = RootFolder.GetAllChildren().FirstOrDefault(vm => vm.ProfileElement == e.RenderProfileElement);
|
||||
if (match != null)
|
||||
SelectedTreeItem = match;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -16,10 +16,9 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileTree.TreeItem
|
||||
{
|
||||
private readonly IDialogService _dialogService;
|
||||
private readonly IFolderVmFactory _folderVmFactory;
|
||||
private readonly IRenderElementService _renderElementService;
|
||||
private readonly ILayerVmFactory _layerVmFactory;
|
||||
private readonly IProfileEditorService _profileEditorService;
|
||||
private BindableCollection<TreeItemViewModel> _children;
|
||||
private readonly IRenderElementService _renderElementService;
|
||||
private TreeItemViewModel _parent;
|
||||
private ProfileElement _profileElement;
|
||||
|
||||
@ -41,6 +40,10 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileTree.TreeItem
|
||||
ProfileElement = profileElement;
|
||||
|
||||
Children = new BindableCollection<TreeItemViewModel>();
|
||||
|
||||
ProfileElement.ChildAdded += ProfileElementOnChildAdded;
|
||||
ProfileElement.ChildRemoved += ProfileElementOnChildRemoved;
|
||||
|
||||
UpdateProfileElements();
|
||||
}
|
||||
|
||||
@ -56,16 +59,15 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileTree.TreeItem
|
||||
set => SetAndNotify(ref _profileElement, value);
|
||||
}
|
||||
|
||||
public BindableCollection<TreeItemViewModel> Children
|
||||
{
|
||||
get => _children;
|
||||
set => SetAndNotify(ref _children, value);
|
||||
}
|
||||
public BindableCollection<TreeItemViewModel> Children { get; }
|
||||
|
||||
public abstract bool SupportsChildren { get; }
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
ProfileElement.ChildAdded -= ProfileElementOnChildAdded;
|
||||
ProfileElement.ChildRemoved -= ProfileElementOnChildRemoved;
|
||||
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
@ -94,7 +96,6 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileTree.TreeItem
|
||||
|
||||
Parent.ProfileElement.RemoveChild(source.ProfileElement);
|
||||
Parent.ProfileElement.AddChild(source.ProfileElement, ProfileElement.Order);
|
||||
Parent.UpdateProfileElements();
|
||||
}
|
||||
|
||||
public void SetElementBehind(TreeItemViewModel source)
|
||||
@ -107,7 +108,6 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileTree.TreeItem
|
||||
|
||||
Parent.ProfileElement.RemoveChild(source.ProfileElement);
|
||||
Parent.ProfileElement.AddChild(source.ProfileElement, ProfileElement.Order + 1);
|
||||
Parent.UpdateProfileElements();
|
||||
}
|
||||
|
||||
public void RemoveExistingElement(TreeItemViewModel treeItem)
|
||||
@ -118,6 +118,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileTree.TreeItem
|
||||
ProfileElement.RemoveChild(treeItem.ProfileElement);
|
||||
Children.Remove(treeItem);
|
||||
treeItem.Parent = null;
|
||||
treeItem.Dispose();
|
||||
}
|
||||
|
||||
public void AddExistingElement(TreeItemViewModel treeItem)
|
||||
@ -136,7 +137,6 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileTree.TreeItem
|
||||
throw new ArtemisUIException("Cannot add a folder to a profile element of type " + ProfileElement.GetType().Name);
|
||||
|
||||
ProfileElement.AddChild(new Folder(ProfileElement.Profile, ProfileElement, "New folder"));
|
||||
UpdateProfileElements();
|
||||
_profileEditorService.UpdateSelectedProfile();
|
||||
}
|
||||
|
||||
@ -146,7 +146,6 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileTree.TreeItem
|
||||
throw new ArtemisUIException("Cannot add a layer to a profile element of type " + ProfileElement.GetType().Name);
|
||||
|
||||
_renderElementService.CreateLayer(ProfileElement.Profile, ProfileElement, "New layer");
|
||||
UpdateProfileElements();
|
||||
_profileEditorService.UpdateSelectedProfile();
|
||||
}
|
||||
|
||||
@ -182,7 +181,6 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileTree.TreeItem
|
||||
var parent = Parent;
|
||||
ProfileElement.Parent?.RemoveChild(ProfileElement);
|
||||
parent.RemoveExistingElement(this);
|
||||
parent.UpdateProfileElements();
|
||||
|
||||
_profileEditorService.UpdateSelectedProfile();
|
||||
}
|
||||
@ -236,5 +234,15 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileTree.TreeItem
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
private void ProfileElementOnChildRemoved(object sender, EventArgs e)
|
||||
{
|
||||
UpdateProfileElements();
|
||||
}
|
||||
|
||||
private void ProfileElementOnChildAdded(object sender, EventArgs e)
|
||||
{
|
||||
UpdateProfileElements();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,5 @@
|
||||
using System.ComponentModel;
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
using System.Timers;
|
||||
@ -21,45 +22,50 @@ namespace Artemis.UI.Screens
|
||||
{
|
||||
public class RootViewModel : Conductor<IScreen>
|
||||
{
|
||||
private readonly IRegistrationService _builtInRegistrationService;
|
||||
private readonly ISnackbarMessageQueue _snackbarMessageQueue;
|
||||
private readonly PluginSetting<ApplicationColorScheme> _colorScheme;
|
||||
private readonly ICoreService _coreService;
|
||||
private readonly IDebugService _debugService;
|
||||
private readonly IRegistrationService _builtInRegistrationService;
|
||||
private readonly IEventAggregator _eventAggregator;
|
||||
private readonly ThemeWatcher _themeWatcher;
|
||||
private readonly Timer _titleUpdateTimer;
|
||||
private readonly PluginSetting<WindowSize> _windowSize;
|
||||
private bool _lostFocus;
|
||||
private bool _isSidebarVisible;
|
||||
private bool _activeItemReady;
|
||||
private bool _isSidebarVisible;
|
||||
private bool _lostFocus;
|
||||
private string _windowTitle;
|
||||
private ISnackbarMessageQueue _mainMessageQueue;
|
||||
|
||||
public RootViewModel(IEventAggregator eventAggregator, SidebarViewModel sidebarViewModel, ISettingsService settingsService, ICoreService coreService,
|
||||
IDebugService debugService, IRegistrationService builtInRegistrationService, ISnackbarMessageQueue snackbarMessageQueue)
|
||||
{
|
||||
SidebarViewModel = sidebarViewModel;
|
||||
MainMessageQueue = snackbarMessageQueue;
|
||||
_eventAggregator = eventAggregator;
|
||||
_coreService = coreService;
|
||||
_debugService = debugService;
|
||||
_builtInRegistrationService = builtInRegistrationService;
|
||||
_snackbarMessageQueue = snackbarMessageQueue;
|
||||
|
||||
_titleUpdateTimer = new Timer(500);
|
||||
_titleUpdateTimer.Elapsed += (sender, args) => UpdateWindowTitle();
|
||||
|
||||
_colorScheme = settingsService.GetSetting("UI.ColorScheme", ApplicationColorScheme.Automatic);
|
||||
_windowSize = settingsService.GetSetting<WindowSize>("UI.RootWindowSize");
|
||||
_colorScheme.SettingChanged += (sender, args) => ApplyColorSchemeSetting();
|
||||
|
||||
_themeWatcher = new ThemeWatcher();
|
||||
_themeWatcher.ThemeChanged += (sender, args) => ApplyWindowsTheme(args.Theme);
|
||||
ApplyColorSchemeSetting();
|
||||
|
||||
ActiveItem = SidebarViewModel.SelectedItem;
|
||||
ActiveItemReady = true;
|
||||
SidebarViewModel.PropertyChanged += SidebarViewModelOnPropertyChanged;
|
||||
}
|
||||
|
||||
public SidebarViewModel SidebarViewModel { get; }
|
||||
public ISnackbarMessageQueue MainMessageQueue { get; }
|
||||
|
||||
public ISnackbarMessageQueue MainMessageQueue
|
||||
{
|
||||
get => _mainMessageQueue;
|
||||
set => SetAndNotify(ref _mainMessageQueue, value);
|
||||
}
|
||||
|
||||
public bool IsSidebarVisible
|
||||
{
|
||||
@ -112,6 +118,7 @@ namespace Artemis.UI.Screens
|
||||
{
|
||||
_eventAggregator.Publish(new MainWindowKeyEvent(sender, false, e));
|
||||
}
|
||||
|
||||
public void WindowMouseDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
_eventAggregator.Publish(new MainWindowMouseEvent(sender, true, e));
|
||||
@ -176,6 +183,21 @@ namespace Artemis.UI.Screens
|
||||
extensionsPaletteHelper.SetLightDark(colorScheme == ApplicationColorScheme.Dark);
|
||||
}
|
||||
|
||||
private void OnTitleUpdateTimerOnElapsed(object sender, ElapsedEventArgs args)
|
||||
{
|
||||
UpdateWindowTitle();
|
||||
}
|
||||
|
||||
private void ThemeWatcherOnThemeChanged(object sender, WindowsThemeEventArgs e)
|
||||
{
|
||||
ApplyWindowsTheme(e.Theme);
|
||||
}
|
||||
|
||||
private void ColorSchemeOnSettingChanged(object sender, EventArgs e)
|
||||
{
|
||||
ApplyColorSchemeSetting();
|
||||
}
|
||||
|
||||
#region Overrides of Screen
|
||||
|
||||
protected override void OnViewLoaded()
|
||||
@ -194,22 +216,54 @@ namespace Artemis.UI.Screens
|
||||
|
||||
protected override void OnActivate()
|
||||
{
|
||||
MainMessageQueue = _snackbarMessageQueue;
|
||||
UpdateWindowTitle();
|
||||
_titleUpdateTimer.Start();
|
||||
|
||||
_builtInRegistrationService.RegisterBuiltInDataModelDisplays();
|
||||
_builtInRegistrationService.RegisterBuiltInDataModelInputs();
|
||||
_builtInRegistrationService.RegisterBuiltInPropertyEditors();
|
||||
|
||||
_titleUpdateTimer.Elapsed += OnTitleUpdateTimerOnElapsed;
|
||||
_colorScheme.SettingChanged += ColorSchemeOnSettingChanged;
|
||||
_themeWatcher.ThemeChanged += ThemeWatcherOnThemeChanged;
|
||||
SidebarViewModel.PropertyChanged += SidebarViewModelOnPropertyChanged;
|
||||
|
||||
_titleUpdateTimer.Start();
|
||||
}
|
||||
|
||||
protected override void OnDeactivate()
|
||||
{
|
||||
// Ensure no element with focus can leak, if we don't do this the root VM is retained by Window.EffectiveValues
|
||||
// https://stackoverflow.com/a/30864434
|
||||
Keyboard.ClearFocus();
|
||||
|
||||
MainMessageQueue = null;
|
||||
_titleUpdateTimer.Stop();
|
||||
|
||||
var window = (MaterialWindow) View;
|
||||
_windowSize.Value ??= new WindowSize();
|
||||
_windowSize.Value.ApplyFromWindow(window);
|
||||
_windowSize.Save();
|
||||
|
||||
_titleUpdateTimer.Elapsed -= OnTitleUpdateTimerOnElapsed;
|
||||
_colorScheme.SettingChanged -= ColorSchemeOnSettingChanged;
|
||||
_themeWatcher.ThemeChanged -= ThemeWatcherOnThemeChanged;
|
||||
SidebarViewModel.PropertyChanged -= SidebarViewModelOnPropertyChanged;
|
||||
}
|
||||
|
||||
protected override void OnClose()
|
||||
{
|
||||
SidebarViewModel.Dispose();
|
||||
|
||||
// Lets force the GC to run after closing the window so it is obvious to users watching task manager
|
||||
// that closing the UI will decrease the memory footprint of the application.
|
||||
Task.Run(async () =>
|
||||
{
|
||||
await Task.Delay(TimeSpan.FromSeconds(15));
|
||||
GC.Collect();
|
||||
GC.WaitForPendingFinalizers();
|
||||
GC.Collect();
|
||||
});
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@ -3,7 +3,6 @@ using System.Linq;
|
||||
using System.Timers;
|
||||
using Artemis.Core.Events;
|
||||
using Artemis.Core.Services.Interfaces;
|
||||
using Artemis.UI.Services;
|
||||
using Artemis.UI.Shared.DataModelVisualization.Shared;
|
||||
using Artemis.UI.Shared.Services;
|
||||
using Stylet;
|
||||
@ -16,17 +15,16 @@ namespace Artemis.UI.Screens.Settings.Debug.Tabs
|
||||
private readonly IPluginService _pluginService;
|
||||
private readonly Timer _updateTimer;
|
||||
private bool _isModuleFilterEnabled;
|
||||
private Core.Plugins.Abstract.Module _selectedModule;
|
||||
private DataModelPropertiesViewModel _mainDataModel;
|
||||
private string _propertySearch;
|
||||
private List<Core.Plugins.Abstract.Module> _modules;
|
||||
private string _propertySearch;
|
||||
private Core.Plugins.Abstract.Module _selectedModule;
|
||||
|
||||
public DataModelDebugViewModel(IDataModelVisualizationService dataModelVisualizationService, IPluginService pluginService)
|
||||
{
|
||||
_dataModelVisualizationService = dataModelVisualizationService;
|
||||
_pluginService = pluginService;
|
||||
_updateTimer = new Timer(500);
|
||||
_updateTimer.Elapsed += (sender, args) => MainDataModel.Update(_dataModelVisualizationService);
|
||||
|
||||
DisplayName = "Data model";
|
||||
}
|
||||
@ -77,6 +75,7 @@ namespace Artemis.UI.Screens.Settings.Debug.Tabs
|
||||
{
|
||||
GetDataModel();
|
||||
_updateTimer.Start();
|
||||
_updateTimer.Elapsed += OnUpdateTimerOnElapsed;
|
||||
_pluginService.PluginEnabled += PluginServiceOnPluginToggled;
|
||||
_pluginService.PluginDisabled += PluginServiceOnPluginToggled;
|
||||
|
||||
@ -86,10 +85,16 @@ namespace Artemis.UI.Screens.Settings.Debug.Tabs
|
||||
protected override void OnDeactivate()
|
||||
{
|
||||
_updateTimer.Stop();
|
||||
_updateTimer.Elapsed -= OnUpdateTimerOnElapsed;
|
||||
_pluginService.PluginEnabled -= PluginServiceOnPluginToggled;
|
||||
_pluginService.PluginDisabled -= PluginServiceOnPluginToggled;
|
||||
}
|
||||
|
||||
private void OnUpdateTimerOnElapsed(object sender, ElapsedEventArgs args)
|
||||
{
|
||||
MainDataModel.Update(_dataModelVisualizationService);
|
||||
}
|
||||
|
||||
private void GetDataModel()
|
||||
{
|
||||
MainDataModel = SelectedModule != null
|
||||
|
||||
@ -19,7 +19,7 @@ using Stylet;
|
||||
|
||||
namespace Artemis.UI.Screens.Sidebar
|
||||
{
|
||||
public class SidebarViewModel : PropertyChangedBase, IHandle<RequestSelectSidebarItemEvent>
|
||||
public class SidebarViewModel : PropertyChangedBase, IHandle<RequestSelectSidebarItemEvent>, IDisposable
|
||||
{
|
||||
private readonly IKernel _kernel;
|
||||
private readonly IModuleVmFactory _moduleVmFactory;
|
||||
@ -37,10 +37,10 @@ namespace Artemis.UI.Screens.Sidebar
|
||||
SidebarModules = new Dictionary<INavigationItem, Core.Plugins.Abstract.Module>();
|
||||
SidebarItems = new BindableCollection<INavigationItem>();
|
||||
|
||||
SetupSidebar();
|
||||
_pluginService.PluginEnabled += PluginServiceOnPluginEnabled;
|
||||
_pluginService.PluginDisabled += PluginServiceOnPluginDisabled;
|
||||
|
||||
SetupSidebar();
|
||||
eventAggregator.Subscribe(this);
|
||||
}
|
||||
|
||||
@ -64,7 +64,7 @@ namespace Artemis.UI.Screens.Sidebar
|
||||
|
||||
public void SetupSidebar()
|
||||
{
|
||||
SidebarItems.Clear();
|
||||
SidebarItems.Clear();
|
||||
SidebarModules.Clear();
|
||||
|
||||
// Add all default sidebar items
|
||||
@ -194,5 +194,11 @@ namespace Artemis.UI.Screens.Sidebar
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_pluginService.PluginEnabled -= PluginServiceOnPluginEnabled;
|
||||
_pluginService.PluginDisabled -= PluginServiceOnPluginDisabled;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -51,6 +51,8 @@ namespace Artemis.UI.Screens.Splash
|
||||
_pluginService.CopyingBuildInPlugins -= OnPluginServiceOnCopyingBuildInPlugins;
|
||||
_pluginService.PluginLoading -= OnPluginServiceOnPluginLoading;
|
||||
_pluginService.PluginLoaded -= OnPluginServiceOnPluginLoaded;
|
||||
_pluginService.PluginEnabling -= PluginServiceOnPluginEnabling;
|
||||
_pluginService.PluginEnabled -= PluginServiceOnPluginEnabled;
|
||||
base.OnClose();
|
||||
}
|
||||
|
||||
|
||||
@ -12,13 +12,23 @@
|
||||
<StackPanel Margin="16">
|
||||
<TextBlock Text="{Binding Title}" Style="{StaticResource MaterialDesignHeadline6TextBlock}" />
|
||||
<TextBlock Text="Note: These are not being validated yet" Style="{StaticResource MaterialDesignSubtitle1TextBlock}" />
|
||||
<TextBox materialDesign:HintAssist.Hint="X-coordinate" Text="{Binding X}" Style="{StaticResource MaterialDesignFloatingHintTextBox}" Margin="0 10" />
|
||||
|
||||
<TextBox materialDesign:HintAssist.Hint="Y-coordinate" Text="{Binding Y}" Style="{StaticResource MaterialDesignFloatingHintTextBox}" Margin="0 10" />
|
||||
<TextBox materialDesign:HintAssist.Hint="X-coordinate"
|
||||
Text="{Binding X, UpdateSourceTrigger=PropertyChanged}"
|
||||
Style="{StaticResource MaterialDesignFloatingHintTextBox}"
|
||||
Margin="0 10" />
|
||||
<TextBox materialDesign:HintAssist.Hint="Y-coordinate"
|
||||
Text="{Binding Y, UpdateSourceTrigger=PropertyChanged}"
|
||||
Style="{StaticResource MaterialDesignFloatingHintTextBox}"
|
||||
Margin="0 10" />
|
||||
<TextBox materialDesign:HintAssist.Hint="Scale"
|
||||
Text="{Binding Scale, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource MaterialDesignFloatingHintTextBox}"
|
||||
Margin="0 10" />
|
||||
<TextBox materialDesign:HintAssist.Hint="Rotation"
|
||||
Text="{Binding Rotation, UpdateSourceTrigger=PropertyChanged}"
|
||||
Style="{StaticResource MaterialDesignFloatingHintTextBox}"
|
||||
Margin="0 10" />
|
||||
|
||||
<TextBox materialDesign:HintAssist.Hint="Scale" Text="{Binding Scale}" Style="{StaticResource MaterialDesignFloatingHintTextBox}" Margin="0 10" />
|
||||
|
||||
<TextBox materialDesign:HintAssist.Hint="Rotation" Text="{Binding Rotation}" Style="{StaticResource MaterialDesignFloatingHintTextBox}" Margin="0 10" />
|
||||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
|
||||
<Button Style="{StaticResource MaterialDesignFlatButton}" IsCancel="True" Margin="0 8 8 0"
|
||||
Command="{s:Action Cancel}">
|
||||
|
||||
@ -74,9 +74,13 @@ namespace Artemis.Plugins.LayerBrushes.Noise
|
||||
|
||||
CreateBitmap(width, height);
|
||||
|
||||
var clipPath = new SKPath(Layer.Path);
|
||||
Layer.ExcludePathFromTranslation(clipPath);
|
||||
clipPath = new SKPath(clipPath);
|
||||
// Copy the layer path to use for the clip path
|
||||
using var layerPath = new SKPath(Layer.Path);
|
||||
// Undo any transformations
|
||||
Layer.ExcludePathFromTranslation(layerPath);
|
||||
// Apply the transformations so new ones may be applied, not sure if there is a better way to do this
|
||||
using var clipPath = new SKPath(layerPath);
|
||||
// Zero out the position of the clip path
|
||||
clipPath.Transform(SKMatrix.MakeTranslation(Layer.Path.Bounds.Left * -1, Layer.Path.Bounds.Top * -1));
|
||||
|
||||
// Fill a canvas matching the final area that will be rendered
|
||||
|
||||
@ -7,13 +7,10 @@ namespace Artemis.Plugins.LayerBrushes.Noise.Utilities
|
||||
{
|
||||
private const double STRETCH_2D = -0.211324865405187; //(1/Math.sqrt(2+1)-1)/2;
|
||||
private const double STRETCH_3D = -1.0 / 6.0; //(1/Math.sqrt(3+1)-1)/3;
|
||||
private const double STRETCH_4D = -0.138196601125011; //(1/Math.sqrt(4+1)-1)/4;
|
||||
private const double SQUISH_2D = 0.366025403784439; //(Math.sqrt(2+1)-1)/2;
|
||||
private const double SQUISH_3D = 1.0 / 3.0; //(Math.sqrt(3+1)-1)/3;
|
||||
private const double SQUISH_4D = 0.309016994374947; //(Math.sqrt(4+1)-1)/4;
|
||||
private const double NORM_2D = 1.0 / 47.0;
|
||||
private const double NORM_3D = 1.0 / 103.0;
|
||||
private const double NORM_4D = 1.0 / 30.0;
|
||||
|
||||
private static readonly double[] gradients2D =
|
||||
{
|
||||
@ -34,30 +31,9 @@ namespace Artemis.Plugins.LayerBrushes.Noise.Utilities
|
||||
-11, -4, -4, -4, -11, -4, -4, -4, -11,
|
||||
11, -4, -4, 4, -11, -4, 4, -4, -11
|
||||
};
|
||||
|
||||
private static readonly double[] gradients4D =
|
||||
{
|
||||
3, 1, 1, 1, 1, 3, 1, 1, 1, 1, 3, 1, 1, 1, 1, 3,
|
||||
-3, 1, 1, 1, -1, 3, 1, 1, -1, 1, 3, 1, -1, 1, 1, 3,
|
||||
3, -1, 1, 1, 1, -3, 1, 1, 1, -1, 3, 1, 1, -1, 1, 3,
|
||||
-3, -1, 1, 1, -1, -3, 1, 1, -1, -1, 3, 1, -1, -1, 1, 3,
|
||||
3, 1, -1, 1, 1, 3, -1, 1, 1, 1, -3, 1, 1, 1, -1, 3,
|
||||
-3, 1, -1, 1, -1, 3, -1, 1, -1, 1, -3, 1, -1, 1, -1, 3,
|
||||
3, -1, -1, 1, 1, -3, -1, 1, 1, -1, -3, 1, 1, -1, -1, 3,
|
||||
-3, -1, -1, 1, -1, -3, -1, 1, -1, -1, -3, 1, -1, -1, -1, 3,
|
||||
3, 1, 1, -1, 1, 3, 1, -1, 1, 1, 3, -1, 1, 1, 1, -3,
|
||||
-3, 1, 1, -1, -1, 3, 1, -1, -1, 1, 3, -1, -1, 1, 1, -3,
|
||||
3, -1, 1, -1, 1, -3, 1, -1, 1, -1, 3, -1, 1, -1, 1, -3,
|
||||
-3, -1, 1, -1, -1, -3, 1, -1, -1, -1, 3, -1, -1, -1, 1, -3,
|
||||
3, 1, -1, -1, 1, 3, -1, -1, 1, 1, -3, -1, 1, 1, -1, -3,
|
||||
-3, 1, -1, -1, -1, 3, -1, -1, -1, 1, -3, -1, -1, 1, -1, -3,
|
||||
3, -1, -1, -1, 1, -3, -1, -1, 1, -1, -3, -1, 1, -1, -1, -3,
|
||||
-3, -1, -1, -1, -1, -3, -1, -1, -1, -1, -3, -1, -1, -1, -1, -3
|
||||
};
|
||||
|
||||
|
||||
private static readonly Contribution2[] lookup2D;
|
||||
private static readonly Contribution3[] lookup3D;
|
||||
private static readonly Contribution4[] lookup4D;
|
||||
|
||||
private readonly byte[] perm;
|
||||
private readonly byte[] perm2D;
|
||||
@ -140,101 +116,6 @@ namespace Artemis.Plugins.LayerBrushes.Noise.Utilities
|
||||
lookup3D = new Contribution3[2048];
|
||||
for (var i = 0; i < lookupPairs3D.Length; i += 2)
|
||||
lookup3D[lookupPairs3D[i]] = contributions3D[lookupPairs3D[i + 1]];
|
||||
|
||||
var base4D = new[]
|
||||
{
|
||||
new[] {0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1},
|
||||
new[] {3, 1, 1, 1, 0, 3, 1, 1, 0, 1, 3, 1, 0, 1, 1, 3, 0, 1, 1, 1, 4, 1, 1, 1, 1},
|
||||
new[] {1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 2, 1, 1, 0, 0, 2, 1, 0, 1, 0, 2, 1, 0, 0, 1, 2, 0, 1, 1, 0, 2, 0, 1, 0, 1, 2, 0, 0, 1, 1},
|
||||
new[] {3, 1, 1, 1, 0, 3, 1, 1, 0, 1, 3, 1, 0, 1, 1, 3, 0, 1, 1, 1, 2, 1, 1, 0, 0, 2, 1, 0, 1, 0, 2, 1, 0, 0, 1, 2, 0, 1, 1, 0, 2, 0, 1, 0, 1, 2, 0, 0, 1, 1}
|
||||
};
|
||||
var p4D = new[]
|
||||
{
|
||||
0, 0, 1, -1, 0, 0, 0, 1, 0, -1, 0, 0, 1, 0, 0, -1, 0, 0, -1, 1, 0, 0, 0, 0, 1, -1, 0, 0, 0, 1, 0, -1, 0, 0, -1, 0, 1, 0, 0, 0, -1, 1, 0, 0, 0, 0, 1, -1, 0, 0, -1, 0, 0, 1, 0, 0, -1, 0,
|
||||
1, 0, 0, 0, -1, 1, 0, 2, 1, 1, 0, 0, 1, 1, 1, -1, 0, 1, 1, 1, 0, -1, 0, 2, 1, 0, 1, 0, 1, 1, -1, 1, 0, 1, 1, 0, 1, -1, 0, 2, 0, 1, 1, 0, 1, -1, 1, 1, 0, 1, 0, 1, 1, -1, 0, 2, 1, 0, 0,
|
||||
1, 1, 1, -1, 0, 1, 1, 1, 0, -1, 1, 0, 2, 0, 1, 0, 1, 1, -1, 1, 0, 1, 1, 0, 1, -1, 1, 0, 2, 0, 0, 1, 1, 1, -1, 0, 1, 1, 1, 0, -1, 1, 1, 1, 4, 2, 1, 1, 0, 4, 1, 2, 1, 0, 4, 1, 1, 2, 0,
|
||||
1, 4, 2, 1, 0, 1, 4, 1, 2, 0, 1, 4, 1, 1, 0, 2, 1, 4, 2, 0, 1, 1, 4, 1, 0, 2, 1, 4, 1, 0, 1, 2, 1, 4, 0, 2, 1, 1, 4, 0, 1, 2, 1, 4, 0, 1, 1, 2, 1, 2, 1, 1, 0, 0, 3, 2, 1, 0, 0, 3, 1,
|
||||
2, 0, 0, 1, 2, 1, 0, 1, 0, 3, 2, 0, 1, 0, 3, 1, 0, 2, 0, 1, 2, 0, 1, 1, 0, 3, 0, 2, 1, 0, 3, 0, 1, 2, 0, 1, 2, 1, 0, 0, 1, 3, 2, 0, 0, 1, 3, 1, 0, 0, 2, 1, 2, 0, 1, 0, 1, 3, 0, 2, 0,
|
||||
1, 3, 0, 1, 0, 2, 1, 2, 0, 0, 1, 1, 3, 0, 0, 2, 1, 3, 0, 0, 1, 2, 2, 3, 1, 1, 1, 0, 2, 1, 1, 1, -1, 2, 2, 0, 0, 0, 2, 3, 1, 1, 0, 1, 2, 1, 1, -1, 1, 2, 2, 0, 0, 0, 2, 3, 1, 0, 1, 1, 2,
|
||||
1, -1, 1, 1, 2, 2, 0, 0, 0, 2, 3, 1, 1, 1, 0, 2, 1, 1, 1, -1, 2, 0, 2, 0, 0, 2, 3, 1, 1, 0, 1, 2, 1, 1, -1, 1, 2, 0, 2, 0, 0, 2, 3, 0, 1, 1, 1, 2, -1, 1, 1, 1, 2, 0, 2, 0, 0, 2, 3, 1,
|
||||
1, 1, 0, 2, 1, 1, 1, -1, 2, 0, 0, 2, 0, 2, 3, 1, 0, 1, 1, 2, 1, -1, 1, 1, 2, 0, 0, 2, 0, 2, 3, 0, 1, 1, 1, 2, -1, 1, 1, 1, 2, 0, 0, 2, 0, 2, 3, 1, 1, 0, 1, 2, 1, 1, -1, 1, 2, 0, 0, 0,
|
||||
2, 2, 3, 1, 0, 1, 1, 2, 1, -1, 1, 1, 2, 0, 0, 0, 2, 2, 3, 0, 1, 1, 1, 2, -1, 1, 1, 1, 2, 0, 0, 0, 2, 2, 1, 1, 1, -1, 0, 1, 1, 1, 0, -1, 0, 0, 0, 0, 0, 2, 1, 1, -1, 1, 0, 1, 1, 0, 1,
|
||||
-1, 0, 0, 0, 0, 0, 2, 1, -1, 1, 1, 0, 1, 0, 1, 1, -1, 0, 0, 0, 0, 0, 2, 1, 1, -1, 0, 1, 1, 1, 0, -1, 1, 0, 0, 0, 0, 0, 2, 1, -1, 1, 0, 1, 1, 0, 1, -1, 1, 0, 0, 0, 0, 0, 2, 1, -1, 0, 1,
|
||||
1, 1, 0, -1, 1, 1, 0, 0, 0, 0, 0, 2, 1, 1, 1, -1, 0, 1, 1, 1, 0, -1, 2, 2, 0, 0, 0, 2, 1, 1, -1, 1, 0, 1, 1, 0, 1, -1, 2, 2, 0, 0, 0, 2, 1, 1, -1, 0, 1, 1, 1, 0, -1, 1, 2, 2, 0, 0, 0,
|
||||
2, 1, 1, 1, -1, 0, 1, 1, 1, 0, -1, 2, 0, 2, 0, 0, 2, 1, -1, 1, 1, 0, 1, 0, 1, 1, -1, 2, 0, 2, 0, 0, 2, 1, -1, 1, 0, 1, 1, 0, 1, -1, 1, 2, 0, 2, 0, 0, 2, 1, 1, -1, 1, 0, 1, 1, 0, 1, -1,
|
||||
2, 0, 0, 2, 0, 2, 1, -1, 1, 1, 0, 1, 0, 1, 1, -1, 2, 0, 0, 2, 0, 2, 1, -1, 0, 1, 1, 1, 0, -1, 1, 1, 2, 0, 0, 2, 0, 2, 1, 1, -1, 0, 1, 1, 1, 0, -1, 1, 2, 0, 0, 0, 2, 2, 1, -1, 1, 0, 1,
|
||||
1, 0, 1, -1, 1, 2, 0, 0, 0, 2, 2, 1, -1, 0, 1, 1, 1, 0, -1, 1, 1, 2, 0, 0, 0, 2, 3, 1, 1, 0, 0, 0, 2, 2, 0, 0, 0, 2, 1, 1, 1, -1, 3, 1, 0, 1, 0, 0, 2, 0, 2, 0, 0, 2, 1, 1, 1, -1, 3, 1,
|
||||
0, 0, 1, 0, 2, 0, 0, 2, 0, 2, 1, 1, 1, -1, 3, 1, 1, 0, 0, 0, 2, 2, 0, 0, 0, 2, 1, 1, -1, 1, 3, 1, 0, 1, 0, 0, 2, 0, 2, 0, 0, 2, 1, 1, -1, 1, 3, 1, 0, 0, 0, 1, 2, 0, 0, 0, 2, 2, 1, 1,
|
||||
-1, 1, 3, 1, 1, 0, 0, 0, 2, 2, 0, 0, 0, 2, 1, -1, 1, 1, 3, 1, 0, 0, 1, 0, 2, 0, 0, 2, 0, 2, 1, -1, 1, 1, 3, 1, 0, 0, 0, 1, 2, 0, 0, 0, 2, 2, 1, -1, 1, 1, 3, 1, 0, 1, 0, 0, 2, 0, 2, 0,
|
||||
0, 2, -1, 1, 1, 1, 3, 1, 0, 0, 1, 0, 2, 0, 0, 2, 0, 2, -1, 1, 1, 1, 3, 1, 0, 0, 0, 1, 2, 0, 0, 0, 2, 2, -1, 1, 1, 1, 3, 3, 2, 1, 0, 0, 3, 1, 2, 0, 0, 4, 1, 1, 1, 1, 3, 3, 2, 0, 1, 0,
|
||||
3, 1, 0, 2, 0, 4, 1, 1, 1, 1, 3, 3, 0, 2, 1, 0, 3, 0, 1, 2, 0, 4, 1, 1, 1, 1, 3, 3, 2, 0, 0, 1, 3, 1, 0, 0, 2, 4, 1, 1, 1, 1, 3, 3, 0, 2, 0, 1, 3, 0, 1, 0, 2, 4, 1, 1, 1, 1, 3, 3, 0,
|
||||
0, 2, 1, 3, 0, 0, 1, 2, 4, 1, 1, 1, 1, 3, 3, 2, 1, 0, 0, 3, 1, 2, 0, 0, 2, 1, 1, 1, -1, 3, 3, 2, 0, 1, 0, 3, 1, 0, 2, 0, 2, 1, 1, 1, -1, 3, 3, 0, 2, 1, 0, 3, 0, 1, 2, 0, 2, 1, 1, 1,
|
||||
-1, 3, 3, 2, 1, 0, 0, 3, 1, 2, 0, 0, 2, 1, 1, -1, 1, 3, 3, 2, 0, 0, 1, 3, 1, 0, 0, 2, 2, 1, 1, -1, 1, 3, 3, 0, 2, 0, 1, 3, 0, 1, 0, 2, 2, 1, 1, -1, 1, 3, 3, 2, 0, 1, 0, 3, 1, 0, 2, 0,
|
||||
2, 1, -1, 1, 1, 3, 3, 2, 0, 0, 1, 3, 1, 0, 0, 2, 2, 1, -1, 1, 1, 3, 3, 0, 0, 2, 1, 3, 0, 0, 1, 2, 2, 1, -1, 1, 1, 3, 3, 0, 2, 1, 0, 3, 0, 1, 2, 0, 2, -1, 1, 1, 1, 3, 3, 0, 2, 0, 1, 3,
|
||||
0, 1, 0, 2, 2, -1, 1, 1, 1, 3, 3, 0, 0, 2, 1, 3, 0, 0, 1, 2, 2, -1, 1, 1, 1
|
||||
};
|
||||
var lookupPairs4D = new[]
|
||||
{
|
||||
0, 3, 1, 2, 2, 3, 5, 2, 6, 1, 7, 1, 8, 3, 9, 2, 10, 3, 13, 2, 16, 3, 18, 3, 22, 1, 23, 1, 24, 3, 26, 3, 33, 2, 37, 2, 38, 1, 39, 1, 41, 2, 45, 2, 54, 1, 55, 1, 56, 0, 57, 0, 58, 0, 59,
|
||||
0, 60, 0, 61, 0, 62, 0, 63, 0, 256, 3, 258, 3, 264, 3, 266, 3, 272, 3, 274, 3, 280, 3, 282, 3, 2049, 2, 2053, 2, 2057, 2, 2061, 2, 2081, 2, 2085, 2, 2089, 2, 2093, 2, 2304, 9, 2305, 9,
|
||||
2312, 9, 2313, 9, 16390, 1, 16391, 1, 16406, 1, 16407, 1, 16422, 1, 16423, 1, 16438, 1, 16439, 1, 16642, 8, 16646, 8, 16658, 8, 16662, 8, 18437, 6, 18439, 6, 18469, 6, 18471, 6, 18688,
|
||||
9, 18689, 9, 18690, 8, 18693, 6, 18694, 8, 18695, 6, 18696, 9, 18697, 9, 18706, 8, 18710, 8, 18725, 6, 18727, 6, 131128, 0, 131129, 0, 131130, 0, 131131, 0, 131132, 0, 131133, 0,
|
||||
131134, 0, 131135, 0, 131352, 7, 131354, 7, 131384, 7, 131386, 7, 133161, 5, 133165, 5, 133177, 5, 133181, 5, 133376, 9, 133377, 9, 133384, 9, 133385, 9, 133400, 7, 133402, 7, 133417,
|
||||
5, 133421, 5, 133432, 7, 133433, 5, 133434, 7, 133437, 5, 147510, 4, 147511, 4, 147518, 4, 147519, 4, 147714, 8, 147718, 8, 147730, 8, 147734, 8, 147736, 7, 147738, 7, 147766, 4,
|
||||
147767, 4, 147768, 7, 147770, 7, 147774, 4, 147775, 4, 149509, 6, 149511, 6, 149541, 6, 149543, 6, 149545, 5, 149549, 5, 149558, 4, 149559, 4, 149561, 5, 149565, 5, 149566, 4, 149567,
|
||||
4, 149760, 9, 149761, 9, 149762, 8, 149765, 6, 149766, 8, 149767, 6, 149768, 9, 149769, 9, 149778, 8, 149782, 8, 149784, 7, 149786, 7, 149797, 6, 149799, 6, 149801, 5, 149805, 5,
|
||||
149814, 4, 149815, 4, 149816, 7, 149817, 5, 149818, 7, 149821, 5, 149822, 4, 149823, 4, 149824, 37, 149825, 37, 149826, 36, 149829, 34, 149830, 36, 149831, 34, 149832, 37, 149833, 37,
|
||||
149842, 36, 149846, 36, 149848, 35, 149850, 35, 149861, 34, 149863, 34, 149865, 33, 149869, 33, 149878, 32, 149879, 32, 149880, 35, 149881, 33, 149882, 35, 149885, 33, 149886, 32,
|
||||
149887, 32, 150080, 49, 150082, 48, 150088, 49, 150098, 48, 150104, 47, 150106, 47, 151873, 46, 151877, 45, 151881, 46, 151909, 45, 151913, 44, 151917, 44, 152128, 49, 152129, 46,
|
||||
152136, 49, 152137, 46, 166214, 43, 166215, 42, 166230, 43, 166247, 42, 166262, 41, 166263, 41, 166466, 48, 166470, 43, 166482, 48, 166486, 43, 168261, 45, 168263, 42, 168293, 45,
|
||||
168295, 42, 168512, 31, 168513, 28, 168514, 31, 168517, 28, 168518, 25, 168519, 25, 280952, 40, 280953, 39, 280954, 40, 280957, 39, 280958, 38, 280959, 38, 281176, 47, 281178, 47,
|
||||
281208, 40, 281210, 40, 282985, 44, 282989, 44, 283001, 39, 283005, 39, 283208, 30, 283209, 27, 283224, 30, 283241, 27, 283256, 22, 283257, 22, 297334, 41, 297335, 41, 297342, 38,
|
||||
297343, 38, 297554, 29, 297558, 24, 297562, 29, 297590, 24, 297594, 21, 297598, 21, 299365, 26, 299367, 23, 299373, 26, 299383, 23, 299389, 20, 299391, 20, 299584, 31, 299585, 28,
|
||||
299586, 31, 299589, 28, 299590, 25, 299591, 25, 299592, 30, 299593, 27, 299602, 29, 299606, 24, 299608, 30, 299610, 29, 299621, 26, 299623, 23, 299625, 27, 299629, 26, 299638, 24,
|
||||
299639, 23, 299640, 22, 299641, 22, 299642, 21, 299645, 20, 299646, 21, 299647, 20, 299648, 61, 299649, 60, 299650, 61, 299653, 60, 299654, 59, 299655, 59, 299656, 58, 299657, 57,
|
||||
299666, 55, 299670, 54, 299672, 58, 299674, 55, 299685, 52, 299687, 51, 299689, 57, 299693, 52, 299702, 54, 299703, 51, 299704, 56, 299705, 56, 299706, 53, 299709, 50, 299710, 53,
|
||||
299711, 50, 299904, 61, 299906, 61, 299912, 58, 299922, 55, 299928, 58, 299930, 55, 301697, 60, 301701, 60, 301705, 57, 301733, 52, 301737, 57, 301741, 52, 301952, 79, 301953, 79,
|
||||
301960, 76, 301961, 76, 316038, 59, 316039, 59, 316054, 54, 316071, 51, 316086, 54, 316087, 51, 316290, 78, 316294, 78, 316306, 73, 316310, 73, 318085, 77, 318087, 77, 318117, 70,
|
||||
318119, 70, 318336, 79, 318337, 79, 318338, 78, 318341, 77, 318342, 78, 318343, 77, 430776, 56, 430777, 56, 430778, 53, 430781, 50, 430782, 53, 430783, 50, 431000, 75, 431002, 72,
|
||||
431032, 75, 431034, 72, 432809, 74, 432813, 69, 432825, 74, 432829, 69, 433032, 76, 433033, 76, 433048, 75, 433065, 74, 433080, 75, 433081, 74, 447158, 71, 447159, 68, 447166, 71,
|
||||
447167, 68, 447378, 73, 447382, 73, 447386, 72, 447414, 71, 447418, 72, 447422, 71, 449189, 70, 449191, 70, 449197, 69, 449207, 68, 449213, 69, 449215, 68, 449408, 67, 449409, 67,
|
||||
449410, 66, 449413, 64, 449414, 66, 449415, 64, 449416, 67, 449417, 67, 449426, 66, 449430, 66, 449432, 65, 449434, 65, 449445, 64, 449447, 64, 449449, 63, 449453, 63, 449462, 62,
|
||||
449463, 62, 449464, 65, 449465, 63, 449466, 65, 449469, 63, 449470, 62, 449471, 62, 449472, 19, 449473, 19, 449474, 18, 449477, 16, 449478, 18, 449479, 16, 449480, 19, 449481, 19,
|
||||
449490, 18, 449494, 18, 449496, 17, 449498, 17, 449509, 16, 449511, 16, 449513, 15, 449517, 15, 449526, 14, 449527, 14, 449528, 17, 449529, 15, 449530, 17, 449533, 15, 449534, 14,
|
||||
449535, 14, 449728, 19, 449729, 19, 449730, 18, 449734, 18, 449736, 19, 449737, 19, 449746, 18, 449750, 18, 449752, 17, 449754, 17, 449784, 17, 449786, 17, 451520, 19, 451521, 19,
|
||||
451525, 16, 451527, 16, 451528, 19, 451529, 19, 451557, 16, 451559, 16, 451561, 15, 451565, 15, 451577, 15, 451581, 15, 451776, 19, 451777, 19, 451784, 19, 451785, 19, 465858, 18,
|
||||
465861, 16, 465862, 18, 465863, 16, 465874, 18, 465878, 18, 465893, 16, 465895, 16, 465910, 14, 465911, 14, 465918, 14, 465919, 14, 466114, 18, 466118, 18, 466130, 18, 466134, 18,
|
||||
467909, 16, 467911, 16, 467941, 16, 467943, 16, 468160, 13, 468161, 13, 468162, 13, 468163, 13, 468164, 13, 468165, 13, 468166, 13, 468167, 13, 580568, 17, 580570, 17, 580585, 15,
|
||||
580589, 15, 580598, 14, 580599, 14, 580600, 17, 580601, 15, 580602, 17, 580605, 15, 580606, 14, 580607, 14, 580824, 17, 580826, 17, 580856, 17, 580858, 17, 582633, 15, 582637, 15,
|
||||
582649, 15, 582653, 15, 582856, 12, 582857, 12, 582872, 12, 582873, 12, 582888, 12, 582889, 12, 582904, 12, 582905, 12, 596982, 14, 596983, 14, 596990, 14, 596991, 14, 597202, 11,
|
||||
597206, 11, 597210, 11, 597214, 11, 597234, 11, 597238, 11, 597242, 11, 597246, 11, 599013, 10, 599015, 10, 599021, 10, 599023, 10, 599029, 10, 599031, 10, 599037, 10, 599039, 10,
|
||||
599232, 13, 599233, 13, 599234, 13, 599235, 13, 599236, 13, 599237, 13, 599238, 13, 599239, 13, 599240, 12, 599241, 12, 599250, 11, 599254, 11, 599256, 12, 599257, 12, 599258, 11,
|
||||
599262, 11, 599269, 10, 599271, 10, 599272, 12, 599273, 12, 599277, 10, 599279, 10, 599282, 11, 599285, 10, 599286, 11, 599287, 10, 599288, 12, 599289, 12, 599290, 11, 599293, 10,
|
||||
599294, 11, 599295, 10
|
||||
};
|
||||
var contributions4D = new Contribution4[p4D.Length / 16];
|
||||
for (var i = 0; i < p4D.Length; i += 16)
|
||||
{
|
||||
var baseSet = base4D[p4D[i]];
|
||||
Contribution4 previous = null, current = null;
|
||||
for (var k = 0; k < baseSet.Length; k += 5)
|
||||
{
|
||||
current = new Contribution4(baseSet[k], baseSet[k + 1], baseSet[k + 2], baseSet[k + 3], baseSet[k + 4]);
|
||||
if (previous == null)
|
||||
contributions4D[i / 16] = current;
|
||||
else
|
||||
previous.Next = current;
|
||||
previous = current;
|
||||
}
|
||||
|
||||
current.Next = new Contribution4(p4D[i + 1], p4D[i + 2], p4D[i + 3], p4D[i + 4], p4D[i + 5]);
|
||||
current.Next.Next = new Contribution4(p4D[i + 6], p4D[i + 7], p4D[i + 8], p4D[i + 9], p4D[i + 10]);
|
||||
current.Next.Next.Next = new Contribution4(p4D[i + 11], p4D[i + 12], p4D[i + 13], p4D[i + 14], p4D[i + 15]);
|
||||
}
|
||||
|
||||
lookup4D = new Contribution4[1048576];
|
||||
for (var i = 0; i < lookupPairs4D.Length; i += 2)
|
||||
lookup4D[lookupPairs4D[i]] = contributions4D[lookupPairs4D[i + 1]];
|
||||
}
|
||||
|
||||
public OpenSimplexNoise()
|
||||
@ -377,76 +258,7 @@ namespace Artemis.Plugins.LayerBrushes.Noise.Utilities
|
||||
|
||||
return value * NORM_3D;
|
||||
}
|
||||
|
||||
public double Evaluate(double x, double y, double z, double w)
|
||||
{
|
||||
var stretchOffset = (x + y + z + w) * STRETCH_4D;
|
||||
var xs = x + stretchOffset;
|
||||
var ys = y + stretchOffset;
|
||||
var zs = z + stretchOffset;
|
||||
var ws = w + stretchOffset;
|
||||
|
||||
var xsb = FastFloor(xs);
|
||||
var ysb = FastFloor(ys);
|
||||
var zsb = FastFloor(zs);
|
||||
var wsb = FastFloor(ws);
|
||||
|
||||
var squishOffset = (xsb + ysb + zsb + wsb) * SQUISH_4D;
|
||||
var dx0 = x - (xsb + squishOffset);
|
||||
var dy0 = y - (ysb + squishOffset);
|
||||
var dz0 = z - (zsb + squishOffset);
|
||||
var dw0 = w - (wsb + squishOffset);
|
||||
|
||||
var xins = xs - xsb;
|
||||
var yins = ys - ysb;
|
||||
var zins = zs - zsb;
|
||||
var wins = ws - wsb;
|
||||
|
||||
var inSum = xins + yins + zins + wins;
|
||||
|
||||
var hash =
|
||||
(int) (zins - wins + 1) |
|
||||
((int) (yins - zins + 1) << 1) |
|
||||
((int) (yins - wins + 1) << 2) |
|
||||
((int) (xins - yins + 1) << 3) |
|
||||
((int) (xins - zins + 1) << 4) |
|
||||
((int) (xins - wins + 1) << 5) |
|
||||
((int) inSum << 6) |
|
||||
((int) (inSum + wins) << 8) |
|
||||
((int) (inSum + zins) << 11) |
|
||||
((int) (inSum + yins) << 14) |
|
||||
((int) (inSum + xins) << 17);
|
||||
|
||||
var c = lookup4D[hash];
|
||||
|
||||
var value = 0.0;
|
||||
while (c != null)
|
||||
{
|
||||
var dx = dx0 + c.dx;
|
||||
var dy = dy0 + c.dy;
|
||||
var dz = dz0 + c.dz;
|
||||
var dw = dw0 + c.dw;
|
||||
var attn = 2 - dx * dx - dy * dy - dz * dz - dw * dw;
|
||||
if (attn > 0)
|
||||
{
|
||||
var px = xsb + c.xsb;
|
||||
var py = ysb + c.ysb;
|
||||
var pz = zsb + c.zsb;
|
||||
var pw = wsb + c.wsb;
|
||||
|
||||
var i = perm4D[(perm[(perm[(perm[px & 0xFF] + py) & 0xFF] + pz) & 0xFF] + pw) & 0xFF];
|
||||
var valuePart = gradients4D[i] * dx + gradients4D[i + 1] * dy + gradients4D[i + 2] * dz + gradients4D[i + 3] * dw;
|
||||
|
||||
attn *= attn;
|
||||
value += attn * attn * valuePart;
|
||||
}
|
||||
|
||||
c = c.Next;
|
||||
}
|
||||
|
||||
return value * NORM_4D;
|
||||
}
|
||||
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private static int FastFloor(double x)
|
||||
{
|
||||
@ -491,30 +303,5 @@ namespace Artemis.Plugins.LayerBrushes.Noise.Utilities
|
||||
this.zsb = zsb;
|
||||
}
|
||||
}
|
||||
|
||||
private class Contribution4
|
||||
{
|
||||
public readonly double dw;
|
||||
public readonly double dx;
|
||||
public readonly double dy;
|
||||
public readonly double dz;
|
||||
public readonly int wsb;
|
||||
public readonly int xsb;
|
||||
public readonly int ysb;
|
||||
public readonly int zsb;
|
||||
public Contribution4 Next;
|
||||
|
||||
public Contribution4(double multiplier, int xsb, int ysb, int zsb, int wsb)
|
||||
{
|
||||
dx = -xsb - multiplier * SQUISH_4D;
|
||||
dy = -ysb - multiplier * SQUISH_4D;
|
||||
dz = -zsb - multiplier * SQUISH_4D;
|
||||
dw = -wsb - multiplier * SQUISH_4D;
|
||||
this.xsb = xsb;
|
||||
this.ysb = ysb;
|
||||
this.zsb = zsb;
|
||||
this.wsb = wsb;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user