1
0
mirror of https://github.com/Artemis-RGB/Artemis synced 2025-12-13 05:48:35 +00:00

Merge remote-tracking branch 'origin/development' into development

This commit is contained in:
Robert 2021-04-06 20:04:28 +02:00
commit b342eabe4d
18 changed files with 722 additions and 419 deletions

View File

@ -1,4 +1,5 @@
using System.ComponentModel;
using System.Collections.Specialized;
using System.ComponentModel;
using SkiaSharp;
namespace Artemis.Core
@ -23,17 +24,16 @@ namespace Artemis.Core
if (CurrentValue == null)
return;
for (int index = 0; index < CurrentValue.Stops.Count; index++)
for (int index = 0; index < CurrentValue.Count; index++)
{
int stopIndex = index;
void Setter(SKColor value)
{
CurrentValue.Stops[stopIndex].Color = value;
CurrentValue.OnColorValuesUpdated();
CurrentValue[stopIndex].Color = value;
}
RegisterDataBindingProperty(() => CurrentValue.Stops[stopIndex].Color, Setter, new ColorStopDataBindingConverter(), $"Color #{stopIndex + 1}");
RegisterDataBindingProperty(() => CurrentValue[stopIndex].Color, Setter, new ColorStopDataBindingConverter(), $"Color #{stopIndex + 1}");
}
}
@ -61,17 +61,17 @@ namespace Artemis.Core
if (_subscribedGradient != BaseValue)
{
if (_subscribedGradient != null)
_subscribedGradient.PropertyChanged -= SubscribedGradientOnPropertyChanged;
_subscribedGradient.CollectionChanged -= SubscribedGradientOnPropertyChanged;
_subscribedGradient = BaseValue;
_subscribedGradient.PropertyChanged += SubscribedGradientOnPropertyChanged;
_subscribedGradient.CollectionChanged += SubscribedGradientOnPropertyChanged;
}
CreateDataBindingRegistrations();
}
private void SubscribedGradientOnPropertyChanged(object? sender, PropertyChangedEventArgs e)
private void SubscribedGradientOnPropertyChanged(object? sender, NotifyCollectionChangedEventArgs args)
{
if (CurrentValue.Stops.Count != GetAllDataBindingRegistrations().Count)
if (CurrentValue.Count != GetAllDataBindingRegistrations().Count)
CreateDataBindingRegistrations();
}

View File

@ -1,5 +1,8 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Linq;
using SkiaSharp;
@ -8,7 +11,7 @@ namespace Artemis.Core
/// <summary>
/// A gradient containing a list of <see cref="ColorGradientStop" />s
/// </summary>
public class ColorGradient : CorePropertyChanged
public class ColorGradient : IList<ColorGradientStop>, INotifyCollectionChanged
{
private static readonly SKColor[] FastLedRainbow =
{
@ -23,19 +26,16 @@ namespace Artemis.Core
new(0xFFFF0000) // and back to Red
};
private readonly List<ColorGradientStop> _stops;
/// <summary>
/// Creates a new instance of the <see cref="ColorGradient" /> class
/// </summary>
public ColorGradient()
{
Stops = new List<ColorGradientStop>();
_stops = new List<ColorGradientStop>();
}
/// <summary>
/// Gets a list of all the <see cref="ColorGradientStop" />s in the gradient
/// </summary>
public List<ColorGradientStop> Stops { get; }
/// <summary>
/// Gets all the colors in the color gradient
/// </summary>
@ -49,13 +49,16 @@ namespace Artemis.Core
{
List<SKColor> result = new();
if (timesToRepeat == 0)
result = Stops.Select(c => c.Color).ToList();
{
result = this.Select(c => c.Color).ToList();
}
else
{
List<SKColor> colors = Stops.Select(c => c.Color).ToList();
List<SKColor> colors = this.Select(c => c.Color).ToList();
for (int i = 0; i <= timesToRepeat; i++)
result.AddRange(colors);
}
if (seamless && !IsSeamless())
result.Add(result[0]);
@ -77,11 +80,13 @@ namespace Artemis.Core
{
List<float> result = new();
if (timesToRepeat == 0)
result = Stops.Select(c => c.Position).ToList();
{
result = this.Select(c => c.Position).ToList();
}
else
{
// Create stops and a list of divided stops
List<float> stops = Stops.Select(c => c.Position / (timesToRepeat + 1)).ToList();
List<float> stops = this.Select(c => c.Position / (timesToRepeat + 1)).ToList();
// For each repeat cycle, add the base stops to the end result
for (int i = 0; i <= timesToRepeat; i++)
@ -104,25 +109,16 @@ namespace Artemis.Core
return result.ToArray();
}
/// <summary>
/// Triggers a property changed event of the <see cref="Stops" /> collection
/// </summary>
public void OnColorValuesUpdated()
{
Stops.Sort((a, b) => a.Position.CompareTo(b.Position));
OnPropertyChanged(nameof(Stops));
}
/// <summary>
/// Gets a color at any position between 0.0 and 1.0 using interpolation
/// </summary>
/// <param name="position">A position between 0.0 and 1.0</param>
public SKColor GetColor(float position)
{
if (!Stops.Any())
if (!this.Any())
return SKColor.Empty;
ColorGradientStop[] stops = Stops.ToArray();
ColorGradientStop[] stops = this.ToArray();
if (position <= 0) return stops[0].Color;
if (position >= 1) return stops[^1].Color;
ColorGradientStop left = stops[0];
@ -160,7 +156,7 @@ namespace Artemis.Core
{
SKColor skColor = FastLedRainbow[index];
float position = 1f / (FastLedRainbow.Length - 1f) * index;
gradient.Stops.Add(new ColorGradientStop(skColor, position));
gradient.Add(new ColorGradientStop(skColor, position));
}
return gradient;
@ -172,7 +168,141 @@ namespace Artemis.Core
/// <returns><see langword="true" /> if the gradient is seamless; <see langword="false" /> otherwise</returns>
public bool IsSeamless()
{
return Stops.Count == 0 || Stops.First().Color.Equals(Stops.Last().Color);
return Count == 0 || this.First().Color.Equals(this.Last().Color);
}
internal void Sort()
{
_stops.Sort((a, b) => a.Position.CompareTo(b.Position));
}
private void ItemOnPropertyChanged(object? sender, PropertyChangedEventArgs e)
{
Sort();
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
#region Implementation of IEnumerable
/// <inheritdoc />
public IEnumerator<ColorGradientStop> GetEnumerator()
{
return _stops.GetEnumerator();
}
/// <inheritdoc />
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
#endregion
#region Implementation of ICollection<ColorGradientStop>
/// <inheritdoc />
public void Add(ColorGradientStop item)
{
_stops.Add(item);
item.PropertyChanged += ItemOnPropertyChanged;
Sort();
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, _stops.IndexOf(item)));
}
/// <inheritdoc />
public void Clear()
{
foreach (ColorGradientStop item in _stops)
item.PropertyChanged -= ItemOnPropertyChanged;
_stops.Clear();
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
/// <inheritdoc />
public bool Contains(ColorGradientStop item)
{
return _stops.Contains(item);
}
/// <inheritdoc />
public void CopyTo(ColorGradientStop[] array, int arrayIndex)
{
_stops.CopyTo(array, arrayIndex);
}
/// <inheritdoc />
public bool Remove(ColorGradientStop item)
{
item.PropertyChanged -= ItemOnPropertyChanged;
int index = _stops.IndexOf(item);
bool removed = _stops.Remove(item);
if (removed)
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item, index));
return removed;
}
/// <inheritdoc />
public int Count => _stops.Count;
/// <inheritdoc />
public bool IsReadOnly => false;
#endregion
#region Implementation of IList<ColorGradientStop>
/// <inheritdoc />
public int IndexOf(ColorGradientStop item)
{
return _stops.IndexOf(item);
}
/// <inheritdoc />
public void Insert(int index, ColorGradientStop item)
{
_stops.Insert(index, item);
item.PropertyChanged += ItemOnPropertyChanged;
Sort();
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item, _stops.IndexOf(item)));
}
/// <inheritdoc />
public void RemoveAt(int index)
{
_stops[index].PropertyChanged -= ItemOnPropertyChanged;
_stops.RemoveAt(index);
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, index));
}
/// <inheritdoc />
public ColorGradientStop this[int index]
{
get => _stops[index];
set
{
ColorGradientStop? oldValue = _stops[index];
oldValue.PropertyChanged -= ItemOnPropertyChanged;
_stops[index] = value;
_stops[index].PropertyChanged += ItemOnPropertyChanged;
Sort();
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, value, oldValue));
}
}
#endregion
#region Implementation of INotifyCollectionChanged
/// <inheritdoc />
public event NotifyCollectionChangedEventHandler? CollectionChanged;
private void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
CollectionChanged?.Invoke(this, e);
}
#endregion
}
}

View File

@ -297,6 +297,9 @@ namespace Artemis.Core
private void ApplyTimeline(Timeline timeline)
{
if (timeline.Delta == TimeSpan.Zero)
return;
General.Update(timeline);
Transform.Update(timeline);
if (LayerBrush != null)

View File

@ -33,6 +33,11 @@ namespace Artemis.Core
/// </summary>
Type PropertyType { get; }
/// <summary>
/// Indicates whether the BaseValue was loaded from storage, useful to check whether a default value must be applied
/// </summary>
bool IsLoadedFromStorage { get; }
/// <summary>
/// Initializes the layer property
/// <para>

View File

@ -0,0 +1,28 @@
namespace Artemis.Core.LayerBrushes
{
/// <summary>
/// Represents a brush preset for a brush.
/// </summary>
public interface ILayerBrushPreset
{
/// <summary>
/// Gets the name of the preset
/// </summary>
string Name { get; }
/// <summary>
/// Gets the description of the preset
/// </summary>
string Description { get; }
/// <summary>
/// Gets the icon of the preset
/// </summary>
string Icon { get; }
/// <summary>
/// Applies the preset to the layer brush
/// </summary>
void Apply();
}
}

View File

@ -1,4 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using SkiaSharp;
namespace Artemis.Core.LayerBrushes
@ -70,6 +72,16 @@ namespace Artemis.Core.LayerBrushes
/// </summary>
public virtual LayerPropertyGroup? BaseProperties => null;
/// <summary>
/// Gets a list of presets available to this layer brush
/// </summary>
public virtual List<ILayerBrushPreset>? Presets => null;
/// <summary>
/// Gets the default preset used for new instances of this layer brush
/// </summary>
public virtual ILayerBrushPreset? DefaultPreset => Presets?.FirstOrDefault();
/// <summary>
/// Gets or sets whether the brush supports transformations
/// <para>Note: RGB.NET brushes can never be transformed and setting this to true will throw an exception</para>

View File

@ -1,4 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace Artemis.Core.LayerBrushes
{

View File

@ -38,7 +38,7 @@
<Rectangle Stroke="{DynamicResource NormalBorderBrush}" Cursor="Hand" MouseUp="UIElement_OnMouseUp">
<Rectangle.Fill>
<LinearGradientBrush
GradientStops="{Binding ColorGradient.Stops, Mode=OneWay, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}, Converter={StaticResource ColorGradientToGradientStopsConverter}}"
GradientStops="{Binding ColorGradient, Mode=OneWay, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}, Converter={StaticResource ColorGradientToGradientStopsConverter}}"
EndPoint="1,0"
StartPoint="0,0" />
</Rectangle.Fill>

View File

@ -14,18 +14,18 @@ namespace Artemis.UI.Shared
/// Converts <see cref="T:Artemis.Core.Models.Profile.ColorGradient" /> into a
/// <see cref="T:System.Windows.Media.GradientStopCollection" />.
/// </summary>
[ValueConversion(typeof(List<ColorGradientStop>), typeof(GradientStopCollection))]
[ValueConversion(typeof(ColorGradient), typeof(GradientStopCollection))]
public class ColorGradientToGradientStopsConverter : IValueConverter
{
/// <inheritdoc />
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
List<ColorGradientStop> colorGradients = (List<ColorGradientStop>) value;
ColorGradient? colorGradient = value as ColorGradient;
GradientStopCollection collection = new();
if (colorGradients == null)
if (colorGradient == null)
return collection;
foreach (ColorGradientStop c in colorGradients.OrderBy(s => s.Position))
foreach (ColorGradientStop c in colorGradient.OrderBy(s => s.Position))
collection.Add(new GradientStop(Color.FromArgb(c.Color.Alpha, c.Color.Red, c.Color.Green, c.Color.Blue), c.Position));
return collection;
}
@ -33,8 +33,8 @@ namespace Artemis.UI.Shared
/// <inheritdoc />
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
GradientStopCollection collection = (GradientStopCollection) value;
List<ColorGradientStop> colorGradients = new();
GradientStopCollection? collection = value as GradientStopCollection;
ColorGradient colorGradients = new();
if (collection == null)
return colorGradients;

View File

@ -20,7 +20,6 @@ namespace Artemis.UI.Shared.Screens.GradientEditor
{
_gradientEditorViewModel = gradientEditorViewModel;
ColorStop = colorStop;
ColorStop.PropertyChanged += ColorStopOnPropertyChanged;
}
public ColorGradientStop ColorStop { get; }
@ -59,11 +58,6 @@ namespace Artemis.UI.Shared.Screens.GradientEditor
set => SetAndNotify(ref _willRemoveColorStop, value);
}
private void ColorStopOnPropertyChanged(object? sender, PropertyChangedEventArgs e)
{
_gradientEditorViewModel.ColorGradient.OnColorValuesUpdated();
}
#region Movement
public void StopMouseDown(object sender, MouseButtonEventArgs e)
@ -102,7 +96,7 @@ namespace Artemis.UI.Shared.Screens.GradientEditor
double minValue = 0.0;
double maxValue = _gradientEditorViewModel.PreviewWidth;
List<ColorGradientStop> stops = _gradientEditorViewModel.ColorGradient.Stops.OrderBy(s => s.Position).ToList();
List<ColorGradientStop> stops = _gradientEditorViewModel.ColorGradient.ToList();
ColorGradientStop? previous = stops.IndexOf(ColorStop) >= 1 ? stops[stops.IndexOf(ColorStop) - 1] : null;
ColorGradientStop? next = stops.IndexOf(ColorStop) + 1 < stops.Count ? stops[stops.IndexOf(ColorStop) + 1] : null;
if (previous != null)
@ -111,7 +105,6 @@ namespace Artemis.UI.Shared.Screens.GradientEditor
maxValue = next.Position * _gradientEditorViewModel.PreviewWidth;
Offset = Math.Max(minValue, Math.Min(maxValue, position.X));
_gradientEditorViewModel.ColorGradient.OnColorValuesUpdated();
}
#endregion

View File

@ -66,7 +66,7 @@
<Rectangle x:Name="Preview" Height="40" shared:SizeObserver.Observe="True" shared:SizeObserver.ObservedWidth="{Binding PreviewWidth, Mode=OneWayToSource}">
<Rectangle.Fill>
<LinearGradientBrush
GradientStops="{Binding ColorGradient.Stops, Converter={StaticResource ColorGradientToGradientStopsConverter}}"
GradientStops="{Binding ColorGradient, Converter={StaticResource ColorGradientToGradientStopsConverter}}"
EndPoint="1,0"
StartPoint="0,0" />
</Rectangle.Fill>

View File

@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Linq;
using System.Windows;
@ -6,6 +7,7 @@ using System.Windows.Controls;
using System.Windows.Input;
using Artemis.Core;
using Artemis.UI.Shared.Services;
using MaterialDesignThemes.Wpf;
using Stylet;
namespace Artemis.UI.Shared.Screens.GradientEditor
@ -21,12 +23,24 @@ namespace Artemis.UI.Shared.Screens.GradientEditor
ColorGradient = colorGradient;
ColorStopViewModels = new BindableCollection<ColorStopViewModel>();
_originalStops = ColorGradient.Stops.Select(s => new ColorGradientStop(s.Color, s.Position)).ToList();
_originalStops = ColorGradient.Select(s => new ColorGradientStop(s.Color, s.Position)).ToList();
PropertyChanged += UpdateColorStopViewModels;
ColorGradient.CollectionChanged += ColorGradientOnCollectionChanged;
}
public BindableCollection<ColorStopViewModel> ColorStopViewModels { get; set; }
#region Overrides of DialogViewModelBase
/// <inheritdoc />
public override void OnDialogClosed(object sender, DialogClosingEventArgs e)
{
ColorGradient.CollectionChanged -= ColorGradientOnCollectionChanged;
base.OnDialogClosed(sender, e);
}
#endregion
public BindableCollection<ColorStopViewModel> ColorStopViewModels { get; }
public ColorStopViewModel? SelectedColorStopViewModel
{
@ -48,15 +62,19 @@ namespace Artemis.UI.Shared.Screens.GradientEditor
set => SetAndNotify(ref _previewWidth, value);
}
public ColorGradient Stops
{
get => ColorGradient;
}
public void AddColorStop(object sender, MouseEventArgs e)
{
Canvas? child = VisualTreeUtilities.FindChild<Canvas>((DependencyObject) sender, null);
float position = (float) (e.GetPosition(child).X / PreviewWidth);
ColorGradientStop stop = new(ColorGradient.GetColor(position), position);
ColorGradient.Stops.Add(stop);
ColorGradient.OnColorValuesUpdated();
ColorGradient.Add(stop);
int index = ColorGradient.Stops.OrderBy(s => s.Position).ToList().IndexOf(stop);
int index = ColorGradient.IndexOf(stop);
ColorStopViewModel viewModel = new(this, stop);
ColorStopViewModels.Insert(index, viewModel);
@ -69,8 +87,7 @@ namespace Artemis.UI.Shared.Screens.GradientEditor
return;
ColorStopViewModels.Remove(colorStopViewModel);
ColorGradient.Stops.Remove(colorStopViewModel.ColorStop);
ColorGradient.OnColorValuesUpdated();
ColorGradient.Remove(colorStopViewModel.ColorStop);
SelectColorStop(null);
}
@ -97,9 +114,9 @@ namespace Artemis.UI.Shared.Screens.GradientEditor
public override void Cancel()
{
// Restore the saved state
ColorGradient.Stops.Clear();
ColorGradient.Stops.AddRange(_originalStops);
ColorGradient.OnColorValuesUpdated();
ColorGradient.Clear();
foreach (ColorGradientStop colorGradientStop in _originalStops)
ColorGradient.Add(colorGradientStop);
base.Cancel();
}
@ -107,8 +124,13 @@ namespace Artemis.UI.Shared.Screens.GradientEditor
private void UpdateColorStopViewModels(object? sender, PropertyChangedEventArgs e)
{
if (e.PropertyName != nameof(PreviewWidth)) return;
foreach (ColorGradientStop colorStop in ColorGradient.Stops.OrderBy(s => s.Position))
foreach (ColorGradientStop colorStop in ColorGradient)
ColorStopViewModels.Add(new ColorStopViewModel(this, colorStop));
}
private void ColorGradientOnCollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
{
NotifyOfPropertyChange(nameof(ColorGradient));
}
}
}

View File

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows;
using System.Windows.Controls.Primitives;
using Artemis.Core;
using Artemis.Core.Modules;
using Artemis.Core.Services;
@ -86,7 +87,7 @@ namespace Artemis.UI.Shared.Services
{
if (_currentTime.Equals(value)) return;
_currentTime = value;
UpdateProfilePreview();
Tick();
OnCurrentTimeChanged();
}
}
@ -180,16 +181,9 @@ namespace Artemis.UI.Shared.Services
public void UpdateProfilePreview()
{
if (SelectedProfile == null)
if (Playing)
return;
// Stick to the main segment for any element that is not currently selected
foreach (Folder folder in SelectedProfile.GetAllFolders())
folder.Timeline.Override(CurrentTime, folder.Timeline.PlayMode == TimelinePlayMode.Repeat);
foreach (Layer layer in SelectedProfile.GetAllLayers())
layer.Timeline.Override(CurrentTime, (layer != SelectedProfileElement || layer.Timeline.Length < CurrentTime) && layer.Timeline.PlayMode == TimelinePlayMode.Repeat);
_coreService.FrameRendered += CoreServiceOnFrameRendered;
Tick();
}
public bool UndoUpdateProfile()
@ -357,6 +351,20 @@ namespace Artemis.UI.Shared.Services
.ToList();
}
private void Tick()
{
if (SelectedProfile == null)
return;
// Stick to the main segment for any element that is not currently selected
foreach (Folder folder in SelectedProfile.GetAllFolders())
folder.Timeline.Override(CurrentTime, folder.Timeline.PlayMode == TimelinePlayMode.Repeat);
foreach (Layer layer in SelectedProfile.GetAllLayers())
layer.Timeline.Override(CurrentTime, (layer != SelectedProfileElement || layer.Timeline.Length < CurrentTime) && layer.Timeline.PlayMode == TimelinePlayMode.Repeat);
_coreService.FrameRendered += CoreServiceOnFrameRendered;
}
#region Copy/paste
public ProfileElement? DuplicateProfileElement(ProfileElement profileElement)

View File

@ -1,8 +1,10 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Artemis.Core;
using Artemis.Core.LayerBrushes;
using Artemis.Core.Services;
using Artemis.UI.Screens.ProfileEditor.Dialogs;
using Artemis.UI.Shared;
using Artemis.UI.Shared.Services;
using Stylet;
@ -12,12 +14,15 @@ namespace Artemis.UI.DefaultTypes.PropertyInput
public class BrushPropertyInputViewModel : PropertyInputViewModel<LayerBrushReference>
{
private readonly IPluginManagementService _pluginManagementService;
private readonly IDialogService _dialogService;
private BindableCollection<LayerBrushDescriptor> _descriptors;
public BrushPropertyInputViewModel(LayerProperty<LayerBrushReference> layerProperty, IProfileEditorService profileEditorService, IPluginManagementService pluginManagementService)
public BrushPropertyInputViewModel(LayerProperty<LayerBrushReference> layerProperty, IProfileEditorService profileEditorService, IPluginManagementService pluginManagementService,
IDialogService dialogService)
: base(layerProperty, profileEditorService)
{
_pluginManagementService = pluginManagementService;
_dialogService = dialogService;
UpdateEnumValues();
}
@ -43,7 +48,17 @@ namespace Artemis.UI.DefaultTypes.PropertyInput
protected override void OnInputValueApplied()
{
if (LayerProperty.ProfileElement is Layer layer)
{
layer.ChangeLayerBrush(SelectedDescriptor);
if (layer.LayerBrush?.Presets != null && layer.LayerBrush.Presets.Any())
{
Execute.PostToUIThread(async () =>
{
await Task.Delay(400);
_dialogService.ShowDialogAt<LayerBrushPresetViewModel>("LayerProperties", new Dictionary<string, object> {{"layerBrush", layer.LayerBrush}});
});
}
}
}
private void SetBrushByDescriptor(LayerBrushDescriptor value)

View File

@ -5,6 +5,7 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:s="https://github.com/canton7/Stylet"
xmlns:shared="clr-namespace:Artemis.UI.Shared;assembly=Artemis.UI.Shared"
xmlns:propertyInput="clr-namespace:Artemis.UI.DefaultTypes.PropertyInput"
mc:Ignorable="d"
d:DesignHeight="25" d:DesignWidth="800"
d:DataContext="{d:DesignInstance propertyInput:ColorGradientPropertyInputViewModel}">

View File

@ -0,0 +1,42 @@
<UserControl x:Class="Artemis.UI.Screens.ProfileEditor.Dialogs.LayerBrushPresetView"
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:s="https://github.com/canton7/Stylet"
xmlns:layerBrushes="clr-namespace:Artemis.Core.LayerBrushes;assembly=Artemis.Core"
xmlns:shared="clr-namespace:Artemis.UI.Shared;assembly=Artemis.UI.Shared"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<StackPanel Margin="16">
<TextBlock Style="{StaticResource MaterialDesignHeadline6TextBlock}">
Select a brush preset
</TextBlock>
<ListBox ItemsSource="{Binding Presets}" SelectedItem="{Binding SelectedPreset}" HorizontalContentAlignment="Stretch" Margin="0 8 0 16">
<ListBox.ItemTemplate>
<DataTemplate DataType="{x:Type layerBrushes:ILayerBrushPreset}">
<Border x:Name="Border" Padding="8" BorderThickness="0 0 0 1" BorderBrush="{DynamicResource MaterialDesignDivider}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<shared:ArtemisIcon Icon="{Binding Icon}" VerticalAlignment="Center" Width="30" Height="30"/>
<StackPanel Margin="8 0 0 0" Grid.Column="1">
<TextBlock FontWeight="Bold" Text="{Binding Name}" />
<TextBlock Text="{Binding Description}" />
</StackPanel>
</Grid>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
<Button Style="{StaticResource MaterialDesignFlatButton}" IsDefault="True" Margin="0 8 8 0" Command="{s:Action Cancel}">
USE DEFAULT SETTINGS
</Button>
</StackPanel>
</StackPanel>
</UserControl>

View File

@ -0,0 +1,40 @@
using System.Threading.Tasks;
using Artemis.Core.LayerBrushes;
using Artemis.UI.Shared.Services;
using Stylet;
namespace Artemis.UI.Screens.ProfileEditor.Dialogs
{
public class LayerBrushPresetViewModel : DialogViewModelBase
{
private ILayerBrushPreset _selectedPreset;
public LayerBrushPresetViewModel(BaseLayerBrush layerBrush)
{
Presets = new BindableCollection<ILayerBrushPreset>();
Presets.AddRange(layerBrush.Presets);
}
public BindableCollection<ILayerBrushPreset> Presets { get; }
public ILayerBrushPreset SelectedPreset
{
get => _selectedPreset;
set
{
SetAndNotify(ref _selectedPreset, value);
SelectPreset(value);
}
}
public void SelectPreset(ILayerBrushPreset preset)
{
preset.Apply();
Execute.OnUIThreadAsync(async () =>
{
await Task.Delay(250);
Session?.Close(true);
});
}
}
}

View File

@ -66,6 +66,7 @@
<KeyBinding Command="{s:Action Play}" Key="Space" />
<KeyBinding Command="{s:Action PlayFromStart}" Modifiers="Shift" Key="Space" />
</UserControl.InputBindings>
<materialDesign:DialogHost Identifier="LayerProperties" DialogTheme="Inherit">
<Grid x:Name="ContainerGrid">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
@ -166,7 +167,7 @@
<Border BorderThickness="0,0,1,0" BorderBrush="{DynamicResource MaterialDesignDivider}">
<ContentControl s:View.Model="{Binding TreeViewModel}"
shared:SizeObserver.Observe="True"
shared:SizeObserver.ObservedHeight="{Binding TreeViewModelHeight, Mode=OneWayToSource}"/>
shared:SizeObserver.ObservedHeight="{Binding TreeViewModelHeight, Mode=OneWayToSource}" />
</Border>
</ScrollViewer>
<materialDesign:TransitionerSlide>
@ -204,10 +205,10 @@
</materialDesign:TransitionerSlide.BackwardWipe>
<Grid>
<Grid.InputBindings>
<KeyBinding Key="Delete" Command="{s:Action DeleteKeyframes}" s:View.ActionTarget="{Binding TimelineViewModel}"/>
<KeyBinding Key="Delete" Command="{s:Action DeleteKeyframes}" s:View.ActionTarget="{Binding TimelineViewModel}" />
<KeyBinding Key="D" Modifiers="Control" Command="{s:Action DuplicateKeyframes}" s:View.ActionTarget="{Binding TimelineViewModel}" />
<KeyBinding Key="C" Modifiers="Control" Command="{s:Action CopyKeyframes}" s:View.ActionTarget="{Binding TimelineViewModel}"/>
<KeyBinding Key="V" Modifiers="Control" Command="{s:Action PasteKeyframes}" s:View.ActionTarget="{Binding TimelineViewModel}"/>
<KeyBinding Key="C" Modifiers="Control" Command="{s:Action CopyKeyframes}" s:View.ActionTarget="{Binding TimelineViewModel}" />
<KeyBinding Key="V" Modifiers="Control" Command="{s:Action PasteKeyframes}" s:View.ActionTarget="{Binding TimelineViewModel}" />
</Grid.InputBindings>
<Grid.RowDefinitions>
<RowDefinition Height="48" />
@ -237,7 +238,7 @@
OffsetFirstValue="True"
MouseLeftButtonUp="{s:Action TimelineJump}"
Width="{Binding ActualWidth, ElementName=PropertyTimeLine}"
Cursor="Hand"/>
Cursor="Hand" />
<!-- Timeline caret -->
<Polygon Canvas.Left="{Binding TimeCaretPosition}"
@ -255,7 +256,7 @@
X1="0"
X2="0"
Y1="0"
Y2="{Binding ActualHeight, ElementName=ContainerGrid}"
Y2="{Binding ActualHeight, ElementName=TimelineHeaderScrollViewer}"
StrokeThickness="2"
Stroke="{StaticResource SecondaryAccentBrush}" />
</Canvas>
@ -268,7 +269,7 @@
HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto"
ScrollChanged="TimelineScrollChanged">
<Grid Background="{DynamicResource MaterialDesignToolBarBackground}">
<Grid Background="{DynamicResource MaterialDesignToolBarBackground}" x:Name="RailsGrid">
<Canvas Grid.Column="0" Panel.ZIndex="1">
<Line Canvas.Left="{Binding TimeCaretPosition}"
Cursor="SizeWE"
@ -278,7 +279,7 @@
X1="0"
X2="0"
Y1="0"
Y2="{Binding ActualHeight, ElementName=ContainerGrid}"
Y2="{Binding ActualHeight, ElementName=RailsGrid}"
StrokeThickness="2"
Stroke="{StaticResource SecondaryAccentBrush}" />
</Canvas>
@ -443,4 +444,5 @@
</Grid>
</Grid>
</materialDesign:DialogHost>
</UserControl>