mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-13 05:48:35 +00:00
Merge branch 'development'
This commit is contained in:
commit
a21f1a5555
@ -99,11 +99,12 @@ namespace Artemis.Core
|
||||
/// <inheritdoc />
|
||||
public override void Reset()
|
||||
{
|
||||
DisplayConditionMet = false;
|
||||
Timeline.JumpToEnd();
|
||||
UpdateDisplayCondition();
|
||||
|
||||
foreach (ProfileElement child in Children)
|
||||
child.Reset();
|
||||
if (DisplayConditionMet)
|
||||
Timeline.JumpToStart();
|
||||
else
|
||||
Timeline.JumpToEnd();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@ -202,13 +203,13 @@ namespace Artemis.Core
|
||||
foreach (BaseLayerEffect baseLayerEffect in LayerEffects.Where(e => !e.Suspended))
|
||||
baseLayerEffect.PreProcess(canvas, rendererBounds, layerPaint);
|
||||
|
||||
canvas.SaveLayer(layerPaint);
|
||||
canvas.Translate(Bounds.Left - basePosition.X, Bounds.Top - basePosition.Y);
|
||||
|
||||
// No point rendering if the alpha was set to zero by one of the effects
|
||||
if (layerPaint.Color.Alpha == 0)
|
||||
return;
|
||||
|
||||
canvas.SaveLayer(layerPaint);
|
||||
canvas.Translate(Bounds.Left - basePosition.X, Bounds.Top - basePosition.Y);
|
||||
|
||||
// Iterate the children in reverse because the first layer must be rendered last to end up on top
|
||||
for (int index = Children.Count - 1; index > -1; index--)
|
||||
Children[index].Render(canvas, new SKPointI(Bounds.Left, Bounds.Top));
|
||||
@ -243,6 +244,7 @@ namespace Artemis.Core
|
||||
internal override void Load()
|
||||
{
|
||||
ExpandedPropertyGroups.AddRange(FolderEntity.ExpandedPropertyGroups);
|
||||
Reset();
|
||||
|
||||
// Load child folders
|
||||
foreach (FolderEntity childFolder in Profile.ProfileEntity.Folders.Where(f => f.ParentId == EntityId))
|
||||
|
||||
@ -172,6 +172,9 @@ namespace Artemis.Core
|
||||
|
||||
Disposed = true;
|
||||
|
||||
LayerBrushStore.LayerBrushAdded -= LayerBrushStoreOnLayerBrushAdded;
|
||||
LayerBrushStore.LayerBrushRemoved -= LayerBrushStoreOnLayerBrushRemoved;
|
||||
|
||||
// Brush first in case it depends on any of the other disposables during it's own disposal
|
||||
_layerBrush?.Dispose();
|
||||
_general.Dispose();
|
||||
@ -326,8 +329,12 @@ namespace Artemis.Core
|
||||
/// <inheritdoc />
|
||||
public override void Reset()
|
||||
{
|
||||
DisplayConditionMet = false;
|
||||
Timeline.JumpToEnd();
|
||||
UpdateDisplayCondition();
|
||||
|
||||
if (DisplayConditionMet)
|
||||
Timeline.JumpToStart();
|
||||
else
|
||||
Timeline.JumpToEnd();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@ -355,8 +362,6 @@ namespace Artemis.Core
|
||||
if (Enabled)
|
||||
return;
|
||||
|
||||
Debug.WriteLine($"Enabling {this}");
|
||||
|
||||
LayerBrush?.InternalEnable();
|
||||
foreach (BaseLayerEffect baseLayerEffect in LayerEffects)
|
||||
baseLayerEffect.InternalEnable();
|
||||
@ -370,8 +375,6 @@ namespace Artemis.Core
|
||||
if (!Enabled)
|
||||
return;
|
||||
|
||||
Debug.WriteLine($"Disabling {this}");
|
||||
|
||||
LayerBrush?.InternalDisable();
|
||||
foreach (BaseLayerEffect baseLayerEffect in LayerEffects)
|
||||
baseLayerEffect.InternalDisable();
|
||||
|
||||
@ -125,6 +125,7 @@ namespace Artemis.Core
|
||||
bool stickToMainSegment = Timeline.PlayMode == TimelinePlayMode.Repeat && DisplayConditionMet;
|
||||
if (DisplayCondition != null && DisplayCondition.ContainsEvents)
|
||||
stickToMainSegment = false;
|
||||
|
||||
Timeline.Update(TimeSpan.FromSeconds(deltaTime), stickToMainSegment);
|
||||
}
|
||||
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using Artemis.Storage.Entities.Profile;
|
||||
|
||||
namespace Artemis.Core
|
||||
@ -322,7 +323,7 @@ namespace Artemis.Core
|
||||
|
||||
IsOverridden = false;
|
||||
_lastOverridePosition = Position;
|
||||
|
||||
|
||||
if (stickToMainSegment && Position > MainSegmentEndPosition)
|
||||
{
|
||||
// If the main segment has no length, simply stick to the start of the segment
|
||||
|
||||
@ -61,7 +61,6 @@ namespace Artemis.Core.Modules
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// For internal use only, please use <see cref="Module{T}" />.
|
||||
/// </summary>
|
||||
@ -79,20 +78,15 @@ namespace Artemis.Core.Modules
|
||||
/// Gets a read only collection of default profile paths
|
||||
/// </summary>
|
||||
public IReadOnlyCollection<(DefaultCategoryName, string)> DefaultProfilePaths => _defaultProfilePaths.AsReadOnly();
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The modules display name that's shown in the menu
|
||||
/// </summary>
|
||||
public string? DisplayName { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// The modules display icon that's shown in the UI accepts:
|
||||
/// A list of activation requirements
|
||||
/// <para>
|
||||
/// Either set to the name of a Material Icon see (<see href="https://materialdesignicons.com" /> for available
|
||||
/// icons) or set to a path relative to the plugin folder pointing to a .svg file
|
||||
/// If this list is not <see langword="null" /> and not empty <see cref="IsAlwaysAvailable" /> becomes
|
||||
/// <see langword="false" /> and the data of this module is only available to profiles specifically targeting it.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
public string? DisplayIcon { get; set; }
|
||||
public abstract List<IModuleActivationRequirement>? ActivationRequirements { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets whether this module is activated. A module can only be active while its <see cref="ActivationRequirements" />
|
||||
@ -114,12 +108,6 @@ namespace Artemis.Core.Modules
|
||||
/// </summary>
|
||||
public bool UpdateDuringActivationOverride { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// A list of activation requirements
|
||||
/// <para>Note: if empty the module is always activated</para>
|
||||
/// </summary>
|
||||
public List<IModuleActivationRequirement> ActivationRequirements { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the activation requirement mode, defaults to <see cref="ActivationRequirementType.Any" />
|
||||
/// </summary>
|
||||
@ -133,7 +121,7 @@ namespace Artemis.Core.Modules
|
||||
/// <see langword="false" />
|
||||
/// </para>
|
||||
/// </summary>
|
||||
public bool IsAlwaysAvailable => ActivationRequirements.Count == 0;
|
||||
public bool IsAlwaysAvailable => ActivationRequirements == null || ActivationRequirements.Count == 0;
|
||||
|
||||
/// <summary>
|
||||
/// Gets whether updating this module is currently allowed
|
||||
@ -181,12 +169,12 @@ namespace Artemis.Core.Modules
|
||||
/// <returns>The evaluated result of the activation requirements</returns>
|
||||
public bool EvaluateActivationRequirements()
|
||||
{
|
||||
if (!ActivationRequirements.Any())
|
||||
if (IsAlwaysAvailable)
|
||||
return true;
|
||||
if (ActivationRequirementMode == ActivationRequirementType.All)
|
||||
return ActivationRequirements.All(r => r.Evaluate());
|
||||
return ActivationRequirements!.All(r => r.Evaluate());
|
||||
if (ActivationRequirementMode == ActivationRequirementType.Any)
|
||||
return ActivationRequirements.Any(r => r.Evaluate());
|
||||
return ActivationRequirements!.Any(r => r.Evaluate());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Artemis.Core.DataModelExpansions;
|
||||
using Artemis.Core.DeviceProviders;
|
||||
using Artemis.Core.LayerBrushes;
|
||||
using Artemis.Core.LayerEffects;
|
||||
@ -132,6 +131,19 @@ namespace Artemis.Core
|
||||
internal set => SetAndNotify(ref _instance, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a string representing either a full path pointing to an svg or the markdown icon
|
||||
/// </summary>
|
||||
public string? ResolvedIcon
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Icon == null)
|
||||
return null;
|
||||
return Icon.EndsWith(".svg") ? Plugin.ResolveRelativePath(Icon) : Icon;
|
||||
}
|
||||
}
|
||||
|
||||
internal PluginFeatureEntity Entity { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
@ -152,6 +152,19 @@ namespace Artemis.Core
|
||||
internal set => SetAndNotify(ref _plugin, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a string representing either a full path pointing to an svg or the markdown icon
|
||||
/// </summary>
|
||||
public string? ResolvedIcon
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Icon == null)
|
||||
return null;
|
||||
return Icon.EndsWith(".svg") ? Plugin.ResolveRelativePath(Icon) : Icon;
|
||||
}
|
||||
}
|
||||
|
||||
internal string PreferredPluginDirectory => $"{Main.Split(".dll")[0].Replace("/", "").Replace("\\", "")}-{Guid.ToString().Substring(0, 8)}";
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
@ -26,10 +26,29 @@ namespace Artemis.Core
|
||||
ShowProgressBar = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of a copy folder action
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the action</param>
|
||||
/// <param name="urlFunction">A function returning the URL to download</param>
|
||||
/// <param name="fileName">The target file to save as (will be created if needed)</param>
|
||||
public DownloadFileAction(string name, Func<Task<string>> urlFunction, string fileName) : base(name)
|
||||
{
|
||||
UrlFunction = urlFunction ?? throw new ArgumentNullException(nameof(urlFunction));
|
||||
FileName = fileName ?? throw new ArgumentNullException(nameof(fileName));
|
||||
|
||||
ShowProgressBar = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the source URL to download
|
||||
/// </summary>
|
||||
public string Url { get; }
|
||||
public string? Url { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the function returning the URL to download
|
||||
/// </summary>
|
||||
public Func<Task<string>>? UrlFunction { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the target file to save as (will be created if needed)
|
||||
@ -41,19 +60,25 @@ namespace Artemis.Core
|
||||
{
|
||||
using HttpClient client = new();
|
||||
await using FileStream destinationStream = new(FileName, FileMode.OpenOrCreate);
|
||||
string? url = Url;
|
||||
if (url is null)
|
||||
{
|
||||
Status = "Retrieving download URL";
|
||||
url = await UrlFunction!();
|
||||
}
|
||||
|
||||
void ProgressOnProgressReported(object? sender, EventArgs e)
|
||||
{
|
||||
if (Progress.ProgressPerSecond != 0)
|
||||
Status = $"Downloading {Url} - {Progress.ProgressPerSecond.Bytes().Humanize("#.##")}/sec";
|
||||
Status = $"Downloading {url} - {Progress.ProgressPerSecond.Bytes().Humanize("#.##")}/sec";
|
||||
else
|
||||
Status = $"Downloading {Url}";
|
||||
Status = $"Downloading {url}";
|
||||
}
|
||||
|
||||
Progress.ProgressReported += ProgressOnProgressReported;
|
||||
|
||||
// Get the http headers first to examine the content length
|
||||
using HttpResponseMessage response = await client.GetAsync(Url, HttpCompletionOption.ResponseHeadersRead, cancellationToken);
|
||||
using HttpResponseMessage response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead, cancellationToken);
|
||||
await using Stream download = await response.Content.ReadAsStreamAsync(cancellationToken);
|
||||
long? contentLength = response.Content.Headers.ContentLength;
|
||||
|
||||
|
||||
@ -529,7 +529,7 @@ namespace Artemis.Core.Services
|
||||
|
||||
string targetDirectory = pluginInfo.PreferredPluginDirectory;
|
||||
if (Directory.Exists(Path.Combine(pluginDirectory.FullName, targetDirectory)))
|
||||
throw new ArtemisPluginException($"A directory for this plugin already exists {Path.Combine(pluginDirectory.FullName, targetDirectory)}");
|
||||
Directory.Delete(Path.Combine(pluginDirectory.FullName, targetDirectory), true);
|
||||
|
||||
// Extract everything in the same archive directory to the unique plugin directory
|
||||
DirectoryInfo directoryInfo = new(Path.Combine(pluginDirectory.FullName, targetDirectory));
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
using Artemis.Core.LayerEffects;
|
||||
using System.Collections.Generic;
|
||||
using Artemis.Core.LayerEffects;
|
||||
using Artemis.Core.Modules;
|
||||
|
||||
namespace Artemis.Core
|
||||
@ -14,6 +15,8 @@ namespace Artemis.Core
|
||||
IsEnabled = true;
|
||||
}
|
||||
|
||||
public override List<IModuleActivationRequirement>? ActivationRequirements => null;
|
||||
|
||||
public override void Enable()
|
||||
{
|
||||
}
|
||||
|
||||
@ -41,6 +41,7 @@ namespace Artemis.Storage.Repositories
|
||||
|
||||
public ProfileCategoryEntity IsUnique(string name, Guid? id)
|
||||
{
|
||||
name = name.Trim();
|
||||
if (id == null)
|
||||
return _repository.FirstOrDefault<ProfileCategoryEntity>(p => p.Name == name);
|
||||
return _repository.FirstOrDefault<ProfileCategoryEntity>(p => p.Name == name && p.Id != id.Value);
|
||||
|
||||
@ -53,7 +53,6 @@ namespace Artemis.UI.Shared
|
||||
|
||||
// Run an update timer at 25 fps
|
||||
_timer = new Timer(40);
|
||||
_timer.Elapsed += TimerOnTick;
|
||||
|
||||
MouseLeftButtonUp += OnMouseLeftButtonUp;
|
||||
Loaded += OnLoaded;
|
||||
@ -158,7 +157,8 @@ namespace Artemis.UI.Shared
|
||||
/// </param>
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing) _timer.Stop();
|
||||
if (disposing)
|
||||
_timer.Dispose();
|
||||
}
|
||||
|
||||
|
||||
@ -191,6 +191,7 @@ namespace Artemis.UI.Shared
|
||||
private void OnUnloaded(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
_timer.Stop();
|
||||
_timer.Elapsed -= TimerOnTick;
|
||||
|
||||
if (_oldDevice != null)
|
||||
{
|
||||
@ -222,6 +223,7 @@ namespace Artemis.UI.Shared
|
||||
private void OnLoaded(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
_timer.Start();
|
||||
_timer.Elapsed += TimerOnTick;
|
||||
}
|
||||
|
||||
private void TimerOnTick(object? sender, EventArgs e)
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<UserControl.Resources>
|
||||
<shared:StreamToBitmapImageConverter x:Key="StreamToBitmapImageConverter" />
|
||||
<shared:StreamToSvgImageConverter x:Key="StreamToSvgImageConverter" />
|
||||
</UserControl.Resources>
|
||||
<ContentControl>
|
||||
<ContentControl.Style>
|
||||
@ -47,10 +48,11 @@
|
||||
<Setter Property="ContentTemplate">
|
||||
<Setter.Value>
|
||||
<DataTemplate>
|
||||
<svgc:SvgViewbox StreamSource="{Binding ConfigurationIcon.FileIcon, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"
|
||||
RenderOptions.BitmapScalingMode="HighQuality"
|
||||
Width="Auto"
|
||||
Height="Auto" />
|
||||
<Image
|
||||
Source="{Binding ConfigurationIcon.FileIcon, Converter={StaticResource StreamToSvgImageConverter}, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"
|
||||
RenderOptions.BitmapScalingMode="HighQuality"
|
||||
Width="Auto"
|
||||
Height="Auto" />
|
||||
</DataTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
|
||||
@ -8,7 +8,7 @@ namespace Artemis.UI.Shared
|
||||
{
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// Converts <see cref="T:Stream" /> into <see cref="T:BitmapImage" />.
|
||||
/// Converts bitmap file in the form of a <see cref="T:Stream" /> into <see cref="T:BitmapImage" />.
|
||||
/// </summary>
|
||||
[ValueConversion(typeof(Stream), typeof(BitmapImage))]
|
||||
public class StreamToBitmapImageConverter : IValueConverter
|
||||
@ -16,7 +16,7 @@ namespace Artemis.UI.Shared
|
||||
/// <inheritdoc />
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
if (value is not Stream stream)
|
||||
if (value is not Stream stream)
|
||||
return null;
|
||||
|
||||
stream.Position = 0;
|
||||
|
||||
@ -0,0 +1,48 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Media.Imaging;
|
||||
using SharpVectors.Converters;
|
||||
using SharpVectors.Renderers.Wpf;
|
||||
|
||||
namespace Artemis.UI.Shared
|
||||
{
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// Converts SVG file in the form of a <see cref="T:Stream" /> into <see cref="T:BitmapImage" />.
|
||||
/// </summary>
|
||||
[ValueConversion(typeof(Stream), typeof(BitmapImage))]
|
||||
public class StreamToSvgImageConverter : IValueConverter
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
if (value is not Stream stream)
|
||||
return null;
|
||||
|
||||
stream.Position = 0;
|
||||
|
||||
StreamSvgConverter converter = new(new WpfDrawingSettings());
|
||||
using MemoryStream imageStream = new();
|
||||
converter.Convert(stream, imageStream);
|
||||
|
||||
BitmapImage selectedBitmap = new();
|
||||
selectedBitmap.BeginInit();
|
||||
selectedBitmap.StreamSource = imageStream;
|
||||
selectedBitmap.CacheOption = BitmapCacheOption.OnLoad;
|
||||
selectedBitmap.EndInit();
|
||||
selectedBitmap.Freeze();
|
||||
|
||||
stream.Position = 0;
|
||||
return selectedBitmap;
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc />
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
return Binding.DoNothing;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,43 +0,0 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using Artemis.Core;
|
||||
using MaterialDesignThemes.Wpf;
|
||||
|
||||
namespace Artemis.UI.Shared
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides utilities for UI-related plugin tasks
|
||||
/// </summary>
|
||||
public static class PluginUtilities
|
||||
{
|
||||
/// <summary>
|
||||
/// Transforms the provided icon so that it is usable by the <see cref="ArtemisIcon" /> control
|
||||
/// </summary>
|
||||
/// <param name="plugin">The plugin the icon belongs to</param>
|
||||
/// <param name="icon">
|
||||
/// The icon, may be a string representation of a <see cref="PackIconKind" /> or a relative path
|
||||
/// pointing to a .svg file
|
||||
/// </param>
|
||||
/// <returns></returns>
|
||||
public static object GetPluginIcon(Plugin plugin, string icon)
|
||||
{
|
||||
if (icon == null)
|
||||
return PackIconKind.QuestionMarkCircle;
|
||||
|
||||
// Icon is provided as a path
|
||||
if (icon.EndsWith(".svg"))
|
||||
{
|
||||
string iconPath = plugin.ResolveRelativePath(icon);
|
||||
if (!File.Exists(iconPath))
|
||||
return PackIconKind.QuestionMarkCircle;
|
||||
return iconPath;
|
||||
}
|
||||
|
||||
// Icon is provided as string to avoid having to reference MaterialDesignThemes
|
||||
bool parsedIcon = Enum.TryParse(icon, true, out PackIconKind iconEnum);
|
||||
if (parsedIcon == false)
|
||||
iconEnum = PackIconKind.QuestionMarkCircle;
|
||||
return iconEnum;
|
||||
}
|
||||
}
|
||||
}
|
||||
20
src/Artemis.UI/Converters/ValuesAdditionConverter.cs
Normal file
20
src/Artemis.UI/Converters/ValuesAdditionConverter.cs
Normal file
@ -0,0 +1,20 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace Artemis.UI.Converters
|
||||
{
|
||||
public class ValuesAdditionConverter : IMultiValueConverter
|
||||
{
|
||||
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
return values.Where(v => v is double).Cast<double>().Sum();
|
||||
}
|
||||
|
||||
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -11,7 +11,7 @@
|
||||
<converters:InverseBooleanConverter x:Key="InverseBooleanConverter" />
|
||||
</UserControl.Resources>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Width="25" Text="{Binding LayerProperty.PropertyDescription.InputPrefix}" />
|
||||
<TextBlock Width="25" Text="{Binding LayerProperty.PropertyDescription.InputPrefix}" VerticalAlignment="Center" />
|
||||
<ComboBox Width="132"
|
||||
Margin="0 2"
|
||||
Padding="0 -1"
|
||||
@ -22,6 +22,6 @@
|
||||
<ComboBoxItem Content="True" IsSelected="{Binding InputValue}" />
|
||||
<ComboBoxItem Content="False" IsSelected="{Binding InputValue, Converter={StaticResource InverseBooleanConverter}}" />
|
||||
</ComboBox>
|
||||
<TextBlock Width="25" Text="{Binding LayerProperty.PropertyDescription.InputAffix}" />
|
||||
<TextBlock Width="25" Text="{Binding LayerProperty.PropertyDescription.InputAffix}" VerticalAlignment="Center" />
|
||||
</StackPanel>
|
||||
</UserControl>
|
||||
@ -18,7 +18,7 @@
|
||||
</ResourceDictionary>
|
||||
</UserControl.Resources>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Width="25" Text="{Binding LayerProperty.PropertyDescription.InputPrefix}" />
|
||||
<TextBlock Width="25" Text="{Binding LayerProperty.PropertyDescription.InputPrefix}" VerticalAlignment="Center" />
|
||||
<ComboBox Width="132"
|
||||
Margin="0 2"
|
||||
Padding="0 -1"
|
||||
@ -31,6 +31,6 @@
|
||||
ItemTemplateSelector="{dataTemplateSelectors:ComboBoxTemplateSelector
|
||||
SelectedItemTemplate={StaticResource SimpleLayerBrushDescriptorTemplate},
|
||||
DropdownItemsTemplate={StaticResource ExtendedLayerBrushDescriptorTemplate}}" />
|
||||
<TextBlock Width="25" Text="{Binding LayerProperty.PropertyDescription.InputAffix}" />
|
||||
<TextBlock Width="25" Text="{Binding LayerProperty.PropertyDescription.InputAffix}" VerticalAlignment="Center" />
|
||||
</StackPanel>
|
||||
</UserControl>
|
||||
@ -10,14 +10,14 @@
|
||||
d:DesignHeight="25" d:DesignWidth="800"
|
||||
d:DataContext="{d:DesignInstance propertyInput:ColorGradientPropertyInputViewModel}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Width="25" Text="{Binding LayerProperty.PropertyDescription.InputPrefix}" />
|
||||
<TextBlock Width="25" Text="{Binding LayerProperty.PropertyDescription.InputPrefix}" VerticalAlignment="Center" />
|
||||
<shared:GradientPicker Width="132"
|
||||
Margin="0 2"
|
||||
Padding="0 -1"
|
||||
ColorGradient="{Binding InputValue}"
|
||||
DialogClosed="{s:Action DialogClosed}"
|
||||
DialogHost="PropertyTreeDialogHost"
|
||||
ToolTip="Click to edit gradient colors"/>
|
||||
<TextBlock Width="25" Text="{Binding LayerProperty.PropertyDescription.InputAffix}" />
|
||||
DialogHost="PropertyTreeDialogHost"
|
||||
ToolTip="Click to edit gradient colors" />
|
||||
<TextBlock Width="25" Text="{Binding LayerProperty.PropertyDescription.InputAffix}" VerticalAlignment="Center" />
|
||||
</StackPanel>
|
||||
</UserControl>
|
||||
@ -7,7 +7,7 @@
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Width="25" Text="{Binding LayerProperty.PropertyDescription.InputPrefix}" />
|
||||
<TextBlock Width="25" Text="{Binding LayerProperty.PropertyDescription.InputPrefix}" VerticalAlignment="Center" />
|
||||
<ComboBox Width="132"
|
||||
Margin="0 2"
|
||||
Padding="0 -1"
|
||||
@ -19,6 +19,6 @@
|
||||
SelectedValuePath="Value"
|
||||
DisplayMemberPath="Description"
|
||||
SelectedValue="{Binding Path=InputValue}" />
|
||||
<TextBlock Width="25" Text="{Binding LayerProperty.PropertyDescription.InputAffix}" />
|
||||
<TextBlock Width="25" Text="{Binding LayerProperty.PropertyDescription.InputAffix}" VerticalAlignment="Center" />
|
||||
</StackPanel>
|
||||
</UserControl>
|
||||
@ -11,7 +11,7 @@
|
||||
d:DesignHeight="450" d:DesignWidth="800"
|
||||
d:DataContext="{d:DesignInstance propertyInput:FloatPropertyInputViewModel}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Width="25" Text="{Binding LayerProperty.PropertyDescription.InputPrefix}" />
|
||||
<TextBlock Width="25" Text="{Binding LayerProperty.PropertyDescription.InputPrefix}" VerticalAlignment="Center" />
|
||||
<shared:DraggableFloat Value="{Binding InputValue}"
|
||||
materialDesign:ValidationAssist.UsePopup="True"
|
||||
StepSize="{Binding LayerProperty.PropertyDescription.InputStepSize}"
|
||||
@ -19,7 +19,7 @@
|
||||
Min="{Binding LayerProperty.PropertyDescription.MinInputValue}"
|
||||
DragStarted="{s:Action InputDragStarted}"
|
||||
DragEnded="{s:Action InputDragEnded}"
|
||||
IsEnabled="{Binding IsEnabled}"/>
|
||||
<TextBlock Width="25" Text="{Binding LayerProperty.PropertyDescription.InputAffix}" />
|
||||
IsEnabled="{Binding IsEnabled}" />
|
||||
<TextBlock Width="25" Text="{Binding LayerProperty.PropertyDescription.InputAffix}" VerticalAlignment="Center" />
|
||||
</StackPanel>
|
||||
</UserControl>
|
||||
@ -5,11 +5,12 @@
|
||||
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="450" d:DesignWidth="800"
|
||||
d:DataContext="{d:DesignInstance local:FloatRangePropertyInputViewModel}">
|
||||
d:DataContext="{d:DesignInstance propertyInput:FloatRangePropertyInputViewModel}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Width="25" Text="{Binding LayerProperty.PropertyDescription.InputPrefix}" />
|
||||
<TextBlock Width="25" Text="{Binding LayerProperty.PropertyDescription.InputPrefix}" VerticalAlignment="Center" />
|
||||
<shared:DraggableFloat ToolTip="Start"
|
||||
Value="{Binding Start}"
|
||||
StepSize="{Binding LayerProperty.PropertyDescription.InputStepSize}"
|
||||
@ -17,7 +18,7 @@
|
||||
Min="{Binding LayerProperty.PropertyDescription.MinInputValue}"
|
||||
DragStarted="{s:Action InputDragStarted}"
|
||||
DragEnded="{s:Action InputDragEnded}"
|
||||
IsEnabled="{Binding IsStartEnabled}"/>
|
||||
IsEnabled="{Binding IsStartEnabled}" />
|
||||
<TextBlock Margin="5 0" VerticalAlignment="Bottom">-</TextBlock>
|
||||
<shared:DraggableFloat ToolTip="End"
|
||||
Value="{Binding End}"
|
||||
@ -26,7 +27,7 @@
|
||||
Min="{Binding Start}"
|
||||
DragStarted="{s:Action InputDragStarted}"
|
||||
DragEnded="{s:Action InputDragEnded}"
|
||||
IsEnabled="{Binding IsEndEnabled}"/>
|
||||
<TextBlock Width="25" Text="{Binding LayerProperty.PropertyDescription.InputAffix}" />
|
||||
IsEnabled="{Binding IsEndEnabled}" />
|
||||
<TextBlock Width="25" Text="{Binding LayerProperty.PropertyDescription.InputAffix}" VerticalAlignment="Center" />
|
||||
</StackPanel>
|
||||
</UserControl>
|
||||
@ -6,11 +6,12 @@
|
||||
xmlns:s="https://github.com/canton7/Stylet"
|
||||
xmlns:shared="clr-namespace:Artemis.UI.Shared;assembly=Artemis.UI.Shared"
|
||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||
xmlns:propertyInput="clr-namespace:Artemis.UI.DefaultTypes.PropertyInput"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800"
|
||||
d:DataContext="{d:DesignInstance propertyInput:IntPropertyInputViewModel}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Width="25" Text="{Binding LayerProperty.PropertyDescription.InputPrefix}" />
|
||||
<TextBlock Width="25" Text="{Binding LayerProperty.PropertyDescription.InputPrefix}" VerticalAlignment="Center" />
|
||||
<shared:DraggableFloat Value="{Binding InputValue}"
|
||||
materialDesign:ValidationAssist.UsePopup="True"
|
||||
StepSize="{Binding LayerProperty.PropertyDescription.InputStepSize}"
|
||||
@ -18,7 +19,7 @@
|
||||
Min="{Binding LayerProperty.PropertyDescription.MinInputValue}"
|
||||
DragStarted="{s:Action InputDragStarted}"
|
||||
DragEnded="{s:Action InputDragEnded}"
|
||||
IsEnabled="{Binding IsEnabled}"/>
|
||||
<TextBlock Width="25" Text="{Binding LayerProperty.PropertyDescription.InputAffix}" />
|
||||
IsEnabled="{Binding IsEnabled}" />
|
||||
<TextBlock Width="25" Text="{Binding LayerProperty.PropertyDescription.InputAffix}" VerticalAlignment="Center" />
|
||||
</StackPanel>
|
||||
</UserControl>
|
||||
@ -5,11 +5,12 @@
|
||||
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="450" d:DesignWidth="800"
|
||||
d:DataContext="{d:DesignInstance local:IntRangePropertyInputViewModel}">
|
||||
d:DataContext="{d:DesignInstance propertyInput:IntRangePropertyInputViewModel}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Width="25" Text="{Binding LayerProperty.PropertyDescription.InputPrefix}" />
|
||||
<TextBlock Width="25" Text="{Binding LayerProperty.PropertyDescription.InputPrefix}" VerticalAlignment="Center" />
|
||||
<shared:DraggableFloat ToolTip="Start"
|
||||
Value="{Binding Start}"
|
||||
StepSize="{Binding LayerProperty.PropertyDescription.InputStepSize}"
|
||||
@ -17,7 +18,7 @@
|
||||
Min="{Binding LayerProperty.PropertyDescription.MinInputValue}"
|
||||
DragStarted="{s:Action InputDragStarted}"
|
||||
DragEnded="{s:Action InputDragEnded}"
|
||||
IsEnabled="{Binding IsStartEnabled}"/>
|
||||
IsEnabled="{Binding IsStartEnabled}" />
|
||||
<TextBlock Margin="5 0" VerticalAlignment="Bottom">-</TextBlock>
|
||||
<shared:DraggableFloat ToolTip="End"
|
||||
Value="{Binding End}"
|
||||
@ -26,7 +27,7 @@
|
||||
Min="{Binding Start}"
|
||||
DragStarted="{s:Action InputDragStarted}"
|
||||
DragEnded="{s:Action InputDragEnded}"
|
||||
IsEnabled="{Binding IsEndEnabled}"/>
|
||||
<TextBlock Width="25" Text="{Binding LayerProperty.PropertyDescription.InputAffix}" />
|
||||
IsEnabled="{Binding IsEndEnabled}" />
|
||||
<TextBlock Width="25" Text="{Binding LayerProperty.PropertyDescription.InputAffix}" VerticalAlignment="Center" />
|
||||
</StackPanel>
|
||||
</UserControl>
|
||||
@ -5,6 +5,7 @@
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:artemis="clr-namespace:Artemis.UI.Shared;assembly=Artemis.UI.Shared"
|
||||
xmlns:s="https://github.com/canton7/Stylet"
|
||||
xmlns:propertyInput="clr-namespace:Artemis.UI.DefaultTypes.PropertyInput"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="25" d:DesignWidth="800"
|
||||
d:DataContext="{d:DesignInstance propertyInput:SKColorPropertyInputViewModel}">
|
||||
@ -12,7 +13,7 @@
|
||||
<artemis:SKColorToColorConverter x:Key="SKColorToColorConverter" />
|
||||
</UserControl.Resources>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Width="25" Text="{Binding LayerProperty.PropertyDescription.InputPrefix}" />
|
||||
<TextBlock Width="25" Text="{Binding LayerProperty.PropertyDescription.InputPrefix}" VerticalAlignment="Center" />
|
||||
<artemis:ColorPicker Width="132"
|
||||
Margin="0 -2 0 3"
|
||||
Padding="0 -1"
|
||||
@ -20,6 +21,6 @@
|
||||
IsEnabled="{Binding IsEnabled}"
|
||||
DragStarted="{s:Action InputDragStarted}"
|
||||
DragEnded="{s:Action InputDragEnded}"/>
|
||||
<TextBlock Width="25" Text="{Binding LayerProperty.PropertyDescription.InputAffix}" />
|
||||
<TextBlock Width="25" Text="{Binding LayerProperty.PropertyDescription.InputAffix}" VerticalAlignment="Center" />
|
||||
</StackPanel>
|
||||
</UserControl>
|
||||
@ -5,11 +5,12 @@
|
||||
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:SKPointPropertyInputViewModel}">
|
||||
<StackPanel Orientation="Horizontal" KeyboardNavigation.IsTabStop="True">
|
||||
<TextBlock Width="25" Text="{Binding LayerProperty.PropertyDescription.InputPrefix}" />
|
||||
<TextBlock Width="25" Text="{Binding LayerProperty.PropertyDescription.InputPrefix}" VerticalAlignment="Center" />
|
||||
<shared:DraggableFloat ToolTip="X-coordinate (horizontal)"
|
||||
Value="{Binding X}"
|
||||
StepSize="{Binding LayerProperty.PropertyDescription.InputStepSize}"
|
||||
@ -17,7 +18,7 @@
|
||||
Min="{Binding LayerProperty.PropertyDescription.MinInputValue}"
|
||||
DragStarted="{s:Action InputDragStarted}"
|
||||
DragEnded="{s:Action InputDragEnded}"
|
||||
IsEnabled="{Binding IsXEnabled}"/>
|
||||
IsEnabled="{Binding IsXEnabled}" />
|
||||
<TextBlock Margin="5 0" VerticalAlignment="Bottom">,</TextBlock>
|
||||
<shared:DraggableFloat ToolTip="Y-coordinate (vertical)"
|
||||
Value="{Binding Y}"
|
||||
@ -26,7 +27,7 @@
|
||||
Min="{Binding LayerProperty.PropertyDescription.MinInputValue}"
|
||||
DragStarted="{s:Action InputDragStarted}"
|
||||
DragEnded="{s:Action InputDragEnded}"
|
||||
IsEnabled="{Binding IsYEnabled}"/>
|
||||
<TextBlock Width="25" Text="{Binding LayerProperty.PropertyDescription.InputAffix}" />
|
||||
IsEnabled="{Binding IsYEnabled}" />
|
||||
<TextBlock Width="25" Text="{Binding LayerProperty.PropertyDescription.InputAffix}" VerticalAlignment="Center" />
|
||||
</StackPanel>
|
||||
</UserControl>
|
||||
@ -5,11 +5,12 @@
|
||||
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="450" d:DesignWidth="800"
|
||||
d:DataContext="{d:DesignInstance local:SKSizePropertyInputViewModel}">
|
||||
d:DataContext="{d:DesignInstance propertyInput:SKSizePropertyInputViewModel}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Width="25" Text="{Binding LayerProperty.PropertyDescription.InputPrefix}" />
|
||||
<TextBlock Width="25" Text="{Binding LayerProperty.PropertyDescription.InputPrefix}" VerticalAlignment="Center" />
|
||||
<shared:DraggableFloat ToolTip="Height"
|
||||
Value="{Binding Height}"
|
||||
StepSize="{Binding LayerProperty.PropertyDescription.InputStepSize}"
|
||||
@ -17,7 +18,7 @@
|
||||
Min="{Binding LayerProperty.PropertyDescription.MinInputValue}"
|
||||
DragStarted="{s:Action InputDragStarted}"
|
||||
DragEnded="{s:Action InputDragEnded}"
|
||||
IsEnabled="{Binding IsHeightEnabled}"/>
|
||||
IsEnabled="{Binding IsHeightEnabled}" />
|
||||
<TextBlock Margin="5 0" VerticalAlignment="Bottom">,</TextBlock>
|
||||
<shared:DraggableFloat ToolTip="Width"
|
||||
Value="{Binding Width}"
|
||||
@ -26,7 +27,7 @@
|
||||
Min="{Binding LayerProperty.PropertyDescription.MinInputValue}"
|
||||
DragStarted="{s:Action InputDragStarted}"
|
||||
DragEnded="{s:Action InputDragEnded}"
|
||||
IsEnabled="{Binding IsWidthEnabled}"/>
|
||||
<TextBlock Width="25" Text="{Binding LayerProperty.PropertyDescription.InputAffix}" />
|
||||
IsEnabled="{Binding IsWidthEnabled}" />
|
||||
<TextBlock Width="25" Text="{Binding LayerProperty.PropertyDescription.InputAffix}" VerticalAlignment="Center" />
|
||||
</StackPanel>
|
||||
</UserControl>
|
||||
@ -1,19 +1,19 @@
|
||||
<UserControl
|
||||
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:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||
xmlns:treeItem1="clr-namespace:Artemis.UI.Screens.ProfileEditor.ProfileTree.TreeItem"
|
||||
xmlns:Converters="clr-namespace:Artemis.UI.Converters"
|
||||
xmlns:shared="clr-namespace:Artemis.UI.Shared;assembly=Artemis.UI.Shared"
|
||||
x:Class="Artemis.UI.Screens.ProfileEditor.ProfileTree.TreeItem.LayerView"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800"
|
||||
d:DataContext="{d:DesignInstance {x:Type treeItem1:LayerViewModel}}">
|
||||
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:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||
xmlns:treeItem1="clr-namespace:Artemis.UI.Screens.ProfileEditor.ProfileTree.TreeItem"
|
||||
xmlns:Converters="clr-namespace:Artemis.UI.Converters"
|
||||
xmlns:shared="clr-namespace:Artemis.UI.Shared;assembly=Artemis.UI.Shared"
|
||||
x:Class="Artemis.UI.Screens.ProfileEditor.ProfileTree.TreeItem.LayerView"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800"
|
||||
d:DataContext="{d:DesignInstance {x:Type treeItem1:LayerViewModel}}">
|
||||
<UserControl.Resources>
|
||||
<Converters:InverseBooleanConverter x:Key="InverseBooleanConverter"/>
|
||||
<Converters:InverseBooleanConverter x:Key="InverseBooleanConverter" />
|
||||
</UserControl.Resources>
|
||||
<!-- Capture clicks on full tree view item -->
|
||||
<StackPanel Margin="-10" Background="Transparent" ContextMenuOpening="{s:Action ContextMenuOpening}">
|
||||
@ -72,12 +72,17 @@
|
||||
<TextBlock Grid.Column="2" Text="{Binding Layer.Name}" VerticalAlignment="Center" Margin="5 0 0 0" />
|
||||
<ToggleButton Grid.Column="3"
|
||||
Style="{StaticResource MaterialDesignFlatToggleButton}"
|
||||
ToolTip="Toggle suspended state"
|
||||
Width="18"
|
||||
Height="18"
|
||||
IsChecked="{Binding ProfileElement.Suspended, Converter={StaticResource InverseBooleanConverter}}"
|
||||
Command="{s:Action SuspendedToggled}"
|
||||
VerticalAlignment="Center" Padding="-25">
|
||||
<ToggleButton.ToolTip>
|
||||
<TextBlock>
|
||||
Toggle suspended state <LineBreak />
|
||||
<Bold>Shift+click</Bold> to toggle focus
|
||||
</TextBlock>
|
||||
</ToggleButton.ToolTip>
|
||||
<materialDesign:PackIcon Kind="Eye" Height="13" Width="13" />
|
||||
</ToggleButton>
|
||||
</Grid>
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
using Artemis.Core;
|
||||
using Artemis.Core.LayerBrushes;
|
||||
using Artemis.Core.Services;
|
||||
@ -18,9 +19,9 @@ namespace Artemis.UI.Screens.ProfileEditor.ProfileTree.TreeItem
|
||||
{
|
||||
private readonly IDialogService _dialogService;
|
||||
private readonly ILayerBrushService _layerBrushService;
|
||||
private readonly IRgbService _rgbService;
|
||||
private readonly IProfileEditorService _profileEditorService;
|
||||
private readonly IProfileTreeVmFactory _profileTreeVmFactory;
|
||||
private readonly IRgbService _rgbService;
|
||||
private ProfileElement _profileElement;
|
||||
|
||||
protected TreeItemViewModel(ProfileElement profileElement,
|
||||
@ -243,6 +244,39 @@ namespace Artemis.UI.Screens.ProfileEditor.ProfileTree.TreeItem
|
||||
|
||||
public void SuspendedToggled()
|
||||
{
|
||||
// If shift is held toggle focus state
|
||||
if (Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift))
|
||||
{
|
||||
// Get all profile elements
|
||||
List<ProfileElement> elements = ProfileElement.Profile.GetAllFolders().Cast<ProfileElement>().ToList();
|
||||
elements.AddRange(ProfileElement.Profile.GetAllLayers().Cast<ProfileElement>().ToList());
|
||||
|
||||
// Separate out the targets of the focus state, the current profile element and all its parents
|
||||
List<ProfileElement> targets = ProfileElement.GetAllFolders().Cast<ProfileElement>().ToList();
|
||||
targets.AddRange(ProfileElement.GetAllLayers().Cast<ProfileElement>().ToList());
|
||||
ProfileElement target = ProfileElement;
|
||||
while (target != null)
|
||||
{
|
||||
targets.Add(target);
|
||||
target = target.Parent;
|
||||
}
|
||||
|
||||
// If any element is suspended, untoggle focus and unsuspend everything
|
||||
if (elements.Except(targets).Any(e => e.Suspended))
|
||||
{
|
||||
foreach (ProfileElement profileElement in elements)
|
||||
profileElement.Suspended = false;
|
||||
}
|
||||
// Otherwise suspend everything except the targets
|
||||
else
|
||||
{
|
||||
foreach (ProfileElement profileElement in elements.Except(targets))
|
||||
profileElement.Suspended = true;
|
||||
foreach (ProfileElement profileElement in targets)
|
||||
profileElement.Suspended = false;
|
||||
}
|
||||
}
|
||||
|
||||
_profileEditorService.SaveSelectedProfileConfiguration();
|
||||
}
|
||||
|
||||
|
||||
@ -23,58 +23,63 @@
|
||||
KeyUp="{s:Action WindowKeyUp}"
|
||||
MouseDown="{s:Action WindowMouseDown}"
|
||||
MouseUp="{s:Action WindowMouseUp}"
|
||||
d:DesignHeight="640" d:DesignWidth="1200"
|
||||
d:DesignHeight="640" d:DesignWidth="1200"
|
||||
d:DataContext="{d:DesignInstance screens:RootViewModel}">
|
||||
<materialDesign:DialogHost IsTabStop="False" Focusable="False" Identifier="RootDialog" DialogTheme="Inherit" SnackbarMessageQueue="{Binding MainMessageQueue}">
|
||||
<DockPanel>
|
||||
<Border DockPanel.Dock="Left" DockPanel.ZIndex="2" ClipToBounds="True" Background="{DynamicResource MaterialDesignToolBarBackground}">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition />
|
||||
<ColumnDefinition />
|
||||
</Grid.ColumnDefinitions>
|
||||
<ContentControl Grid.Column="0" s:View.Model="{Binding SidebarViewModel}" Width="240" />
|
||||
<Rectangle Grid.Column="1" Fill="DarkGray" Width="1" Margin="0 0 -1 0">
|
||||
<Rectangle.Effect>
|
||||
<DropShadowEffect ShadowDepth="0" BlurRadius="10" Color="{StaticResource MaterialDesignShadow}" />
|
||||
</Rectangle.Effect>
|
||||
</Rectangle>
|
||||
</Grid>
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="{Binding SidebarWidth.Value, Mode=TwoWay}" MinWidth="175" MaxWidth="400" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Border Grid.Column="0" ClipToBounds="True" Background="{DynamicResource MaterialDesignToolBarBackground}">
|
||||
<ContentControl s:View.Model="{Binding SidebarViewModel}" VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch" IsTabStop="False" />
|
||||
</Border>
|
||||
|
||||
<materialDesign:ColorZone Mode="PrimaryMid" DockPanel.Dock="Top" DockPanel.ZIndex="1" Height="42">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0"
|
||||
Text="{Binding SidebarViewModel.SelectedScreen.DisplayName}"
|
||||
VerticalAlignment="Center"
|
||||
FontSize="20"
|
||||
Margin="15 0" />
|
||||
<StackPanel Grid.Column="1" Orientation="Horizontal">
|
||||
<TextBlock Text="{Binding FrameTime}" VerticalAlignment="Center" FontSize="14" Margin="10 0" ToolTip="The time the last frame took to render" />
|
||||
<GridSplitter Grid.Column="0" Width="8" Margin="0 0 -4 0" Background="Transparent" />
|
||||
|
||||
<!-- Bug: materialDesign:RippleAssist.RippleOnTop doesn't look as nice but otherwise it doesn't work at all, not sure why -->
|
||||
<Button Style="{StaticResource MaterialDesignIconForegroundButton}"
|
||||
VerticalAlignment="Center"
|
||||
ToolTip="Open debugger"
|
||||
Command="{s:Action ShowDebugger}"
|
||||
materialDesign:RippleAssist.RippleOnTop="True">
|
||||
<materialDesign:PackIcon Kind="Matrix" />
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</materialDesign:ColorZone>
|
||||
<Grid Grid.Column="1">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
<materialDesign:ColorZone Grid.Row="0" Mode="PrimaryMid" DockPanel.Dock="Top" DockPanel.ZIndex="1" Height="42">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0"
|
||||
Text="{Binding SidebarViewModel.SelectedScreen.DisplayName}"
|
||||
VerticalAlignment="Center"
|
||||
FontSize="20"
|
||||
Margin="15 0" />
|
||||
<StackPanel Grid.Column="1" Orientation="Horizontal">
|
||||
<TextBlock Text="{Binding FrameTime}" VerticalAlignment="Center" FontSize="14" Margin="10 0" ToolTip="The time the last frame took to render" />
|
||||
|
||||
<Grid>
|
||||
<ContentControl s:View.Model="{Binding SidebarViewModel.SelectedScreen}" />
|
||||
<materialDesign:Snackbar x:Name="MainSnackbar"
|
||||
<!-- Bug: materialDesign:RippleAssist.RippleOnTop doesn't look as nice but otherwise it doesn't work at all, not sure why -->
|
||||
<Button Style="{StaticResource MaterialDesignIconForegroundButton}"
|
||||
VerticalAlignment="Center"
|
||||
ToolTip="Open debugger"
|
||||
Command="{s:Action ShowDebugger}"
|
||||
materialDesign:RippleAssist.RippleOnTop="True">
|
||||
<materialDesign:PackIcon Kind="Matrix" />
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</materialDesign:ColorZone>
|
||||
|
||||
<ContentControl Grid.Row="1"
|
||||
s:View.Model="{Binding SidebarViewModel.SelectedScreen}"
|
||||
VerticalContentAlignment="Stretch"
|
||||
HorizontalContentAlignment="Stretch"
|
||||
IsTabStop="False" />
|
||||
<materialDesign:Snackbar Grid.Row="0"
|
||||
Grid.RowSpan="2"
|
||||
x:Name="MainSnackbar"
|
||||
MessageQueue="{Binding MainMessageQueue}"
|
||||
materialDesign:SnackbarMessage.InlineActionButtonMaxHeight="80"
|
||||
materialDesign:SnackbarMessage.ContentMaxHeight="200" />
|
||||
</Grid>
|
||||
</DockPanel>
|
||||
</Grid>
|
||||
</materialDesign:DialogHost>
|
||||
</mde:MaterialWindow>
|
||||
@ -61,6 +61,7 @@ namespace Artemis.UI.Screens
|
||||
_frameTimeUpdateTimer = new Timer(500);
|
||||
_windowSize = _settingsService.GetSetting<WindowSize>("UI.RootWindowSize");
|
||||
|
||||
SidebarWidth = _settingsService.GetSetting("UI.SidebarWidth", new GridLength(240));
|
||||
SidebarViewModel = sidebarViewModel;
|
||||
SidebarViewModel.ConductWith(this);
|
||||
|
||||
@ -68,6 +69,7 @@ namespace Artemis.UI.Screens
|
||||
WindowTitle = $"Artemis {versionAttribute?.InformationalVersion} build {Constants.BuildInfo.BuildNumberDisplay}";
|
||||
}
|
||||
|
||||
public PluginSetting<GridLength> SidebarWidth { get; }
|
||||
public SidebarViewModel SidebarViewModel { get; }
|
||||
|
||||
public ISnackbarMessageQueue MainMessageQueue
|
||||
@ -75,7 +77,7 @@ namespace Artemis.UI.Screens
|
||||
get => _mainMessageQueue;
|
||||
set => SetAndNotify(ref _mainMessageQueue, value);
|
||||
}
|
||||
|
||||
|
||||
public string WindowTitle
|
||||
{
|
||||
get => _windowTitle;
|
||||
@ -210,7 +212,7 @@ namespace Artemis.UI.Screens
|
||||
_frameTimeUpdateTimer.Stop();
|
||||
|
||||
SidebarViewModel.SelectedScreenChanged -= SidebarViewModelOnSelectedScreenChanged;
|
||||
|
||||
SidebarWidth.Save();
|
||||
_windowSize.Value ??= new WindowSize();
|
||||
_windowSize.Value.ApplyFromWindow(_window);
|
||||
_windowSize.Save();
|
||||
|
||||
@ -142,7 +142,7 @@ namespace Artemis.UI.Screens.Settings.Debug.Tabs
|
||||
private void PopulateModules()
|
||||
{
|
||||
Modules.Clear();
|
||||
Modules.AddRange(_pluginManagementService.GetFeaturesOfType<Module>().Where(p => p.IsEnabled).OrderBy(m => m.DisplayName));
|
||||
Modules.AddRange(_pluginManagementService.GetFeaturesOfType<Module>().Where(p => p.IsEnabled).OrderBy(m => m.Info.Name));
|
||||
|
||||
if (SelectedModule == null)
|
||||
_dataModelUIService.UpdateModules(MainDataModel);
|
||||
|
||||
@ -17,7 +17,7 @@
|
||||
<ColumnDefinition Width="40"/>
|
||||
<ColumnDefinition />
|
||||
</Grid.ColumnDefinitions>
|
||||
<shared:ArtemisIcon Grid.Column="0" Icon="{Binding Icon}" Width="24" Height="24" />
|
||||
<shared:ArtemisIcon Grid.Column="0" Icon="{Binding Plugin.Info.ResolvedIcon}" Width="24" Height="24" />
|
||||
<TextBlock Grid.Column="1" VerticalAlignment="Center" Style="{StaticResource MaterialDesignSubtitle1TextBlock}" Text="{Binding Plugin.Info.Name}" />
|
||||
</Grid>
|
||||
|
||||
|
||||
@ -1,29 +1,25 @@
|
||||
using System.Linq;
|
||||
using Artemis.Core;
|
||||
using Artemis.UI.Shared;
|
||||
using Stylet;
|
||||
|
||||
namespace Artemis.UI.Screens.Settings.Debug.Tabs.Performance
|
||||
{
|
||||
public class PerformanceDebugPluginViewModel : Screen
|
||||
{
|
||||
public Plugin Plugin { get; }
|
||||
public object Icon { get; }
|
||||
|
||||
public PerformanceDebugPluginViewModel(Plugin plugin)
|
||||
{
|
||||
Plugin = plugin;
|
||||
Icon = PluginUtilities.GetPluginIcon(Plugin, Plugin.Info.Icon);
|
||||
}
|
||||
|
||||
public Plugin Plugin { get; }
|
||||
|
||||
public BindableCollection<PerformanceDebugProfilerViewModel> Profilers { get; } = new();
|
||||
|
||||
public void Update()
|
||||
{
|
||||
foreach (Profiler pluginProfiler in Plugin.Profilers.Where(p => p.Measurements.Any()))
|
||||
{
|
||||
if (Profilers.All(p => p.Profiler != pluginProfiler))
|
||||
Profilers.Add(new PerformanceDebugProfilerViewModel(pluginProfiler));
|
||||
}
|
||||
|
||||
foreach (PerformanceDebugProfilerViewModel profilerViewModel in Profilers)
|
||||
profilerViewModel.Update();
|
||||
|
||||
@ -29,8 +29,9 @@
|
||||
|
||||
<!-- Icon column -->
|
||||
<shared:ArtemisIcon Grid.Column="0"
|
||||
Icon="{Binding FeatureInfo.Icon}"
|
||||
Icon="{Binding FeatureInfo.ResolvedIcon}"
|
||||
Width="20"
|
||||
Height="20"
|
||||
VerticalAlignment="Center"
|
||||
HorizontalAlignment="Center"
|
||||
Visibility="{Binding LoadException, Converter={StaticResource NullToVisibilityConverter}, ConverterParameter=Inverted, FallbackValue=Collapsed}" />
|
||||
|
||||
@ -55,6 +55,7 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
|
||||
if (!Items.Contains(pluginSettingsViewModel))
|
||||
Items.Add(pluginSettingsViewModel);
|
||||
}
|
||||
|
||||
foreach (PluginSettingsViewModel pluginSettingsViewModel in Items.ToList())
|
||||
{
|
||||
if (!instances.Contains(pluginSettingsViewModel))
|
||||
@ -76,21 +77,28 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
|
||||
base.OnInitialActivate();
|
||||
}
|
||||
|
||||
public void ImportPlugin()
|
||||
public async Task ImportPlugin()
|
||||
{
|
||||
VistaOpenFileDialog dialog = new();
|
||||
dialog.Filter = "ZIP files (*.zip)|*.zip";
|
||||
dialog.Title = "Import Artemis plugin";
|
||||
VistaOpenFileDialog dialog = new() {Filter = "ZIP files (*.zip)|*.zip", Title = "Import Artemis plugin"};
|
||||
bool? result = dialog.ShowDialog();
|
||||
if (result == true)
|
||||
if (result != true)
|
||||
return;
|
||||
|
||||
// Take the actual import off of the UI thread
|
||||
await Task.Run(() =>
|
||||
{
|
||||
Plugin plugin = _pluginManagementService.ImportPlugin(dialog.FileName);
|
||||
|
||||
GetPluginInstances();
|
||||
SearchPluginInput = plugin.Info.Name;
|
||||
|
||||
// Enable it via the VM to enable the prerequisite dialog
|
||||
PluginSettingsViewModel pluginViewModel = Items.FirstOrDefault(i => i.Plugin == plugin);
|
||||
if (pluginViewModel is {IsEnabled: false})
|
||||
pluginViewModel.IsEnabled = true;
|
||||
|
||||
_messageService.ShowMessage($"Imported plugin: {plugin.Info.Name}");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void GetPluginInstances()
|
||||
|
||||
@ -42,7 +42,7 @@
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<shared:ArtemisIcon Icon="{Binding Icon}"
|
||||
<shared:ArtemisIcon Icon="{Binding Plugin.Info.ResolvedIcon}"
|
||||
Width="48"
|
||||
Height="48"
|
||||
Margin="0 5 0 0"
|
||||
|
||||
@ -45,8 +45,6 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
|
||||
_dialogService = dialogService;
|
||||
_pluginManagementService = pluginManagementService;
|
||||
_messageService = messageService;
|
||||
|
||||
Icon = PluginUtilities.GetPluginIcon(Plugin, Plugin.Info.Icon);
|
||||
}
|
||||
|
||||
public Plugin Plugin
|
||||
@ -60,8 +58,7 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
|
||||
get => _enabling;
|
||||
set => SetAndNotify(ref _enabling, value);
|
||||
}
|
||||
|
||||
public object Icon { get; set; }
|
||||
|
||||
public string Type => Plugin.GetType().BaseType?.Name ?? Plugin.GetType().Name;
|
||||
public bool CanOpenSettings => IsEnabled && Plugin.ConfigurationDialog != null;
|
||||
|
||||
@ -102,7 +99,7 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
|
||||
try
|
||||
{
|
||||
PluginConfigurationViewModel viewModel = (PluginConfigurationViewModel) Plugin.Kernel.Get(configurationViewModel.Type);
|
||||
_windowManager.ShowWindow(new PluginSettingsWindowViewModel(viewModel, Icon));
|
||||
_windowManager.ShowWindow(new PluginSettingsWindowViewModel(viewModel));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
||||
@ -8,10 +8,10 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
|
||||
{
|
||||
private readonly PluginConfigurationViewModel _configurationViewModel;
|
||||
|
||||
public PluginSettingsWindowViewModel(PluginConfigurationViewModel configurationViewModel, object icon)
|
||||
public PluginSettingsWindowViewModel(PluginConfigurationViewModel configurationViewModel)
|
||||
{
|
||||
_configurationViewModel = configurationViewModel ?? throw new ArgumentNullException(nameof(configurationViewModel));
|
||||
Icon = icon;
|
||||
Icon = configurationViewModel.Plugin.Info.Icon;
|
||||
}
|
||||
|
||||
public object Icon { get; }
|
||||
|
||||
@ -36,7 +36,7 @@ namespace Artemis.UI.Screens.Sidebar.Dialogs.ProfileEdit
|
||||
: "any requirement is met";
|
||||
|
||||
Items.Clear();
|
||||
if (Module != null)
|
||||
if (Module?.ActivationRequirements != null)
|
||||
Items.AddRange(Module.ActivationRequirements.Select(_sidebarVmFactory.ModuleActivationRequirementViewModel));
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,10 +6,8 @@
|
||||
xmlns:s="https://github.com/canton7/Stylet"
|
||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||
xmlns:converters="clr-namespace:Artemis.UI.Converters"
|
||||
xmlns:dialogs="clr-namespace:Artemis.UI.Screens.Sidebar.Dialogs"
|
||||
xmlns:shared="clr-namespace:Artemis.UI.Shared;assembly=Artemis.UI.Shared"
|
||||
xmlns:profileEdit="clr-namespace:Artemis.UI.Screens.Sidebar.Dialogs.ProfileEdit"
|
||||
xmlns:svgc="http://sharpvectors.codeplex.com/svgc/"
|
||||
xmlns:core="clr-namespace:Artemis.Core;assembly=Artemis.Core"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="280"
|
||||
@ -17,9 +15,10 @@
|
||||
Width="800">
|
||||
<UserControl.Resources>
|
||||
<converters:InverseBooleanConverter x:Key="InverseBooleanConverter" />
|
||||
<shared:StreamToBitmapImageConverter x:Key="StreamToBitmapImageConverter"/>
|
||||
<shared:NullToVisibilityConverter x:Key="NullToVisibilityConverter" />
|
||||
<shared:BindingProxy x:Key="DataContextProxy" Data="{Binding}" />
|
||||
<shared:NullToVisibilityConverter x:Key="NullToVisibilityConverter" />
|
||||
<shared:StreamToBitmapImageConverter x:Key="StreamToBitmapImageConverter" />
|
||||
<shared:StreamToSvgImageConverter x:Key="StreamToSvgImageConverter" />
|
||||
</UserControl.Resources>
|
||||
<Grid Margin="16">
|
||||
<Grid.RowDefinitions>
|
||||
@ -112,15 +111,16 @@
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition />
|
||||
</Grid.ColumnDefinitions>
|
||||
<materialDesign:PackIcon Grid.Column="0"
|
||||
<materialDesign:PackIcon Grid.Column="0"
|
||||
Kind="{Binding DataContext.SelectedIcon.Icon, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}, Mode=OneWay}"
|
||||
Width="45"
|
||||
Width="45"
|
||||
Height="45"
|
||||
Margin="0 0 10 0"
|
||||
VerticalAlignment="Center" />
|
||||
|
||||
<ComboBox Grid.Column="1"
|
||||
materialDesign:HintAssist.Hint="Profile icon"
|
||||
IsEditable="True"
|
||||
Style="{StaticResource MaterialDesignFilledComboBox}"
|
||||
SelectedItem="{Binding DataContext.SelectedIcon, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"
|
||||
IsEnabled="{Binding DataContext.Initializing, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}, Converter={StaticResource InverseBooleanConverter}}"
|
||||
@ -154,14 +154,14 @@
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Image Grid.Column="0"
|
||||
<Image Grid.Column="0"
|
||||
Source="{Binding DataContext.SelectedImage, Converter={StaticResource StreamToBitmapImageConverter}, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"
|
||||
RenderOptions.BitmapScalingMode="HighQuality"
|
||||
Margin="0 0 10 0"
|
||||
Width="45"
|
||||
Width="45"
|
||||
Height="45"
|
||||
VerticalAlignment="Center" />
|
||||
<Button Grid.Column="1"
|
||||
VerticalAlignment="Center"
|
||||
RenderOptions.BitmapScalingMode="HighQuality" />
|
||||
<Button Grid.Column="1"
|
||||
Command="{s:Action SelectBitmapFile}"
|
||||
Style="{StaticResource MaterialDesignRaisedButton}"
|
||||
ToolTip="Select an image">
|
||||
@ -185,13 +185,14 @@
|
||||
<ColumnDefinition />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<svgc:SvgViewbox Grid.Column="0"
|
||||
StreamSource="{Binding DataContext.SelectedImage, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"
|
||||
Margin="0 0 10 0"
|
||||
Width="45"
|
||||
Height="45"
|
||||
VerticalAlignment="Center" />
|
||||
<Button Grid.Column="1"
|
||||
<Image Grid.Column="0"
|
||||
Source="{Binding DataContext.SelectedImage, Converter={StaticResource StreamToSvgImageConverter}, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"
|
||||
Margin="0 0 10 0"
|
||||
Width="45"
|
||||
Height="45"
|
||||
VerticalAlignment="Center"
|
||||
RenderOptions.BitmapScalingMode="HighQuality" />
|
||||
<Button Grid.Column="1"
|
||||
Command="{s:Action SelectSvgFile}"
|
||||
Style="{StaticResource MaterialDesignRaisedButton}"
|
||||
ToolTip="Select an image">
|
||||
|
||||
@ -9,11 +9,8 @@ namespace Artemis.UI.Screens.Sidebar.Dialogs.ProfileEdit
|
||||
public ProfileModuleViewModel(Module module)
|
||||
{
|
||||
Module = module;
|
||||
Name = module.DisplayName;
|
||||
if (module.DisplayIcon != null)
|
||||
Icon = module.DisplayIcon.EndsWith(".svg") ? module.Plugin.ResolveRelativePath(module.DisplayIcon) : module.DisplayIcon;
|
||||
else
|
||||
Icon = PackIconKind.QuestionMark.ToString();
|
||||
Name = module.Info.Name;
|
||||
Icon = module.Info.ResolvedIcon ?? PackIconKind.QuestionMark.ToString();
|
||||
|
||||
Description = module.Info.Description;
|
||||
}
|
||||
|
||||
@ -18,7 +18,7 @@
|
||||
Padding="8">
|
||||
<!-- Above is a dumb hack to get the context menu to cover the entire item -->
|
||||
<UserControl.Resources>
|
||||
<shared:StreamToBitmapImageConverter x:Key="StreamToBitmapImageConverter" />
|
||||
<converters:ValuesAdditionConverter x:Key="ValuesAddition" />
|
||||
</UserControl.Resources>
|
||||
<UserControl.ContextMenu>
|
||||
<ContextMenu>
|
||||
@ -52,17 +52,17 @@
|
||||
<materialDesign:PackIcon Kind="Export" />
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
<MenuItem Header="Duplicate" Command="{s:Action Duplicate}" >
|
||||
<MenuItem Header="Duplicate" Command="{s:Action Duplicate}">
|
||||
<MenuItem.Icon>
|
||||
<materialDesign:PackIcon Kind="ContentDuplicate" />
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
<MenuItem Header="Copy" Command="{s:Action Copy}" >
|
||||
<MenuItem Header="Copy" Command="{s:Action Copy}">
|
||||
<MenuItem.Icon>
|
||||
<materialDesign:PackIcon Kind="ContentCopy" />
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
<MenuItem Header="Paste" Command="{s:Action Paste}" >
|
||||
<MenuItem Header="Paste" Command="{s:Action Paste}">
|
||||
<MenuItem.Icon>
|
||||
<materialDesign:PackIcon Kind="ContentPaste" />
|
||||
</MenuItem.Icon>
|
||||
@ -77,12 +77,17 @@
|
||||
</UserControl.ContextMenu>
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<shared:ProfileConfigurationIcon Grid.Column="0" VerticalAlignment="Center" ConfigurationIcon="{Binding ProfileConfiguration.Icon}" Width="20" Height="20">
|
||||
<shared:ProfileConfigurationIcon Grid.Column="0"
|
||||
x:Name="ProfileIcon"
|
||||
VerticalAlignment="Center"
|
||||
ConfigurationIcon="{Binding ProfileConfiguration.Icon}"
|
||||
Width="20"
|
||||
Height="20">
|
||||
<shared:ProfileConfigurationIcon.Style>
|
||||
<Style>
|
||||
<Style.Triggers>
|
||||
@ -107,15 +112,22 @@
|
||||
</shared:ProfileConfigurationIcon.Style>
|
||||
</shared:ProfileConfigurationIcon>
|
||||
|
||||
<TextBlock Grid.Column="1" FontSize="12" Margin="10 0 0 0" VerticalAlignment="Center" Text="{Binding ProfileConfiguration.Name}">
|
||||
<TextBlock Grid.Column="1"
|
||||
x:Name="ProfileName"
|
||||
FontSize="12"
|
||||
Margin="10 0 0 0"
|
||||
VerticalAlignment="Center"
|
||||
HorizontalAlignment="Left"
|
||||
Text="{Binding ProfileConfiguration.Name}"
|
||||
TextTrimming="CharacterEllipsis">
|
||||
<TextBlock.Style>
|
||||
<Style>
|
||||
<Style TargetType="TextBlock">
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding IsProfileActive}" Value="False">
|
||||
<DataTrigger.EnterActions>
|
||||
<BeginStoryboard>
|
||||
<Storyboard>
|
||||
<DoubleAnimation Storyboard.TargetProperty="Opacity" To="0.33" Duration="0:0:0.25" />
|
||||
<DoubleAnimation Storyboard.TargetProperty="Opacity" To="0.33" />
|
||||
</Storyboard>
|
||||
</BeginStoryboard>
|
||||
</DataTrigger.EnterActions>
|
||||
@ -132,7 +144,21 @@
|
||||
</TextBlock.Style>
|
||||
</TextBlock>
|
||||
|
||||
<Border Grid.Column="0" Grid.ColumnSpan="2" BorderThickness="1" BorderBrush="{DynamicResource MaterialDesignBody}" Height="1" Opacity="0">
|
||||
<Border Grid.Column="0"
|
||||
Grid.ColumnSpan="2"
|
||||
BorderThickness="1"
|
||||
BorderBrush="{DynamicResource MaterialDesignBody}"
|
||||
Height="1"
|
||||
Opacity="0"
|
||||
HorizontalAlignment="Left">
|
||||
<!-- Ensure the line covers the profile and the text but not the full two columns -->
|
||||
<Border.Width>
|
||||
<MultiBinding Converter="{StaticResource ValuesAddition}">
|
||||
<Binding Path="ActualWidth" ElementName="ProfileIcon" />
|
||||
<Binding Path="ActualWidth" ElementName="ProfileName" />
|
||||
<Binding Path="Margin.Left" ElementName="ProfileName" />
|
||||
</MultiBinding>
|
||||
</Border.Width>
|
||||
<Border.Style>
|
||||
<Style>
|
||||
<Style.Triggers>
|
||||
@ -160,7 +186,7 @@
|
||||
<Button Grid.Column="2" ToolTip="View properties" Width="20" Height="20" Command="{s:Action ViewProperties}" HorizontalAlignment="Right">
|
||||
<Button.Style>
|
||||
<Style TargetType="{x:Type Button}" BasedOn="{StaticResource MaterialDesignIconForegroundButton}">
|
||||
<Setter Property="Visibility" Value="Hidden" />
|
||||
<Setter Property="Visibility" Value="Collapsed" />
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding IsMouseOver, RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}, Mode=FindAncestor}}" Value="True">
|
||||
<Setter Property="Visibility" Value="Visible" />
|
||||
@ -173,7 +199,7 @@
|
||||
<ToggleButton Grid.Column="3" ToolTip="Suspend profile" Width="18" Height="18" Margin="2 0 0 0" IsChecked="{Binding IsSuspended}">
|
||||
<ToggleButton.Style>
|
||||
<Style TargetType="{x:Type ToggleButton}" BasedOn="{StaticResource MaterialDesignFlatToggleButton}">
|
||||
<Setter Property="Visibility" Value="Hidden" />
|
||||
<Setter Property="Visibility" Value="Collapsed" />
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding IsMouseOver, RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}, Mode=FindAncestor}}" Value="True">
|
||||
<Setter Property="Visibility" Value="Visible" />
|
||||
@ -183,6 +209,5 @@
|
||||
</ToggleButton.Style>
|
||||
<materialDesign:PackIcon Kind="Pause" Height="14" Width="14" />
|
||||
</ToggleButton>
|
||||
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@ -119,7 +119,7 @@
|
||||
|
||||
<!-- Bottom buttons -->
|
||||
<Separator Grid.Row="4" Margin="8" />
|
||||
<StackPanel Grid.Row="5" Orientation="Horizontal" HorizontalAlignment="Center" Margin="5 0 5 5">
|
||||
<WrapPanel Grid.Row="5" Orientation="Horizontal" HorizontalAlignment="Left" Margin="5 0 5 5">
|
||||
<Button Style="{StaticResource MaterialDesignIconForegroundButton}"
|
||||
Width="44"
|
||||
Height="44"
|
||||
@ -160,7 +160,7 @@
|
||||
CommandParameter="https://wiki.artemis-rgb.com/en/donating">
|
||||
<materialDesign:PackIcon Kind="Gift" Width="20" Height="20" />
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</WrapPanel>
|
||||
</Grid>
|
||||
</materialDesign:DialogHost>
|
||||
</UserControl>
|
||||
@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Media;
|
||||
@ -129,8 +130,10 @@ namespace Artemis.UI.Screens
|
||||
_eventAggregator.Publish(new RequestSelectSidebarItemEvent(sidebarItem));
|
||||
}
|
||||
|
||||
public void TrayExit()
|
||||
public async Task TrayExit()
|
||||
{
|
||||
// Don't freeze the UI right after clicking
|
||||
await Task.Delay(200);
|
||||
Core.Utilities.Shutdown();
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user