diff --git a/.github/workflows/master.yml b/.github/workflows/master.yml index f7378dab7..36d37e0d3 100644 --- a/.github/workflows/master.yml +++ b/.github/workflows/master.yml @@ -58,7 +58,7 @@ jobs: - name: Setup .NET uses: actions/setup-dotnet@v2 with: - dotnet-version: '6.0.x' + dotnet-version: '7.0.x' - name: Publish Artemis run: dotnet publish --configuration Release -p:Version=${{ needs.version.outputs.version-number }} --runtime ${{ matrix.rid }} --output build/${{ matrix.rid }} --self-contained Artemis/src/Artemis.UI.${{ matrix.csproj }}/Artemis.UI.${{ matrix.csproj }}.csproj - name: Publish Plugins diff --git a/.github/workflows/nuget.yml b/.github/workflows/nuget.yml index fe329b9d9..c45941a79 100644 --- a/.github/workflows/nuget.yml +++ b/.github/workflows/nuget.yml @@ -3,8 +3,6 @@ name: Publish Nuget packages on: workflow_dispatch: push: - branches: - - master jobs: version: @@ -37,7 +35,7 @@ jobs: - name: Setup .NET uses: actions/setup-dotnet@v2 with: - dotnet-version: '6.0.x' + dotnet-version: '7.0.x' - name: Checkout uses: actions/checkout@v3 - name: Pack Artemis.Core diff --git a/src/Artemis.Core/Artemis.Core.csproj b/src/Artemis.Core/Artemis.Core.csproj index 67138efdd..fe9420a6a 100644 --- a/src/Artemis.Core/Artemis.Core.csproj +++ b/src/Artemis.Core/Artemis.Core.csproj @@ -1,6 +1,6 @@  - net6.0 + net7.0 false false Artemis.Core @@ -35,21 +35,22 @@ - - + + - + + - - - - - + + + + + - + diff --git a/src/Artemis.Core/Artemis.Core.csproj.DotSettings b/src/Artemis.Core/Artemis.Core.csproj.DotSettings index 6641be310..fe32d7dc1 100644 --- a/src/Artemis.Core/Artemis.Core.csproj.DotSettings +++ b/src/Artemis.Core/Artemis.Core.csproj.DotSettings @@ -1,4 +1,5 @@ - + True True True diff --git a/src/Artemis.Core/Constants.cs b/src/Artemis.Core/Constants.cs index fd0300579..b5341f3e5 100644 --- a/src/Artemis.Core/Constants.cs +++ b/src/Artemis.Core/Constants.cs @@ -6,7 +6,6 @@ using System.Linq; using System.Reflection; using Artemis.Core.JsonConverters; using Artemis.Core.Services; -using Artemis.Core.Services.Core; using Artemis.Core.SkiaSharp; using Newtonsoft.Json; diff --git a/src/Artemis.Core/DryIoc/ContainerExtensions.cs b/src/Artemis.Core/DryIoc/ContainerExtensions.cs index 927f606a9..b9b768c78 100644 --- a/src/Artemis.Core/DryIoc/ContainerExtensions.cs +++ b/src/Artemis.Core/DryIoc/ContainerExtensions.cs @@ -11,12 +11,12 @@ using DryIoc; namespace Artemis.Core.DryIoc; /// -/// Provides an extension method to register services onto a DryIoc . +/// Provides an extension method to register services onto a DryIoc . /// public static class ContainerExtensions { /// - /// Registers core services into the container. + /// Registers core services into the container. /// /// The builder building the current container public static void RegisterCore(this IContainer container) @@ -37,13 +37,13 @@ public static class ContainerExtensions container.RegisterMany(storageAssembly, type => type.IsAssignableTo(), Reuse.Singleton, nonPublicServiceTypes: true); container.Register(Reuse.Singleton); - container.Register(made: Made.Of(_ => ServiceInfo.Of(), f => f.CreatePluginSettings(Arg.Index(0)), r => r.Parent.ImplementationType)); + container.Register(Made.Of(_ => ServiceInfo.Of(), f => f.CreatePluginSettings(Arg.Index(0)), r => r.Parent.ImplementationType)); container.Register(Reuse.Singleton); - container.Register(made: Made.Of(_ => ServiceInfo.Of(), f => f.CreateLogger(Arg.Index(0)), r => r.Parent.ImplementationType)); + container.Register(Made.Of(_ => ServiceInfo.Of(), f => f.CreateLogger(Arg.Index(0)), r => r.Parent.ImplementationType)); } /// - /// Registers plugin services into the container, this is typically a child container. + /// Registers plugin services into the container, this is typically a child container. /// /// The builder building the current container /// The plugin to register diff --git a/src/Artemis.Core/Events/UpdateEventArgs.cs b/src/Artemis.Core/Events/UpdateEventArgs.cs index d513bae5e..3d8d04de5 100644 --- a/src/Artemis.Core/Events/UpdateEventArgs.cs +++ b/src/Artemis.Core/Events/UpdateEventArgs.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; namespace Artemis.Core; @@ -14,7 +13,7 @@ public class UpdateEventArgs : EventArgs } /// - /// Gets a boolean indicating whether to silently update or not. + /// Gets a boolean indicating whether to silently update or not. /// public bool Silent { get; } } \ No newline at end of file diff --git a/src/Artemis.Core/Exceptions/ArtemisPluginException.cs b/src/Artemis.Core/Exceptions/ArtemisPluginException.cs index 8e49b0e19..53f9fd30f 100644 --- a/src/Artemis.Core/Exceptions/ArtemisPluginException.cs +++ b/src/Artemis.Core/Exceptions/ArtemisPluginException.cs @@ -10,7 +10,7 @@ public class ArtemisPluginException : Exception /// /// Creates a new instance of the class /// - public ArtemisPluginException(Plugin plugin) + internal ArtemisPluginException(Plugin plugin) { Plugin = plugin; } @@ -18,7 +18,7 @@ public class ArtemisPluginException : Exception /// /// Creates a new instance of the class /// - public ArtemisPluginException(Plugin plugin, string message) : base(message) + internal ArtemisPluginException(Plugin plugin, string message) : base(message) { Plugin = plugin; } @@ -26,7 +26,7 @@ public class ArtemisPluginException : Exception /// /// Creates a new instance of the class /// - public ArtemisPluginException(Plugin plugin, string message, Exception inner) : base(message, inner) + internal ArtemisPluginException(Plugin plugin, string message, Exception inner) : base(message, inner) { Plugin = plugin; } @@ -44,9 +44,31 @@ public class ArtemisPluginException : Exception public ArtemisPluginException(string message, Exception inner) : base(message, inner) { } + + /// + /// Creates a new instance of the class + /// + public ArtemisPluginException(string message, string helpDocument) : base(message) + { + HelpDocument = helpDocument; + } + + /// + /// Creates a new instance of the class + /// + public ArtemisPluginException(string message, Exception inner, string helpDocument) : base(message, inner) + { + HelpDocument = helpDocument; + } /// /// Gets the plugin the error is related to /// public Plugin? Plugin { get; } + + /// + /// Gets or sets the help document related to this exception. + /// + public string? HelpDocument { get; } + } \ No newline at end of file diff --git a/src/Artemis.Core/Extensions/ProcessExtensions.cs b/src/Artemis.Core/Extensions/ProcessExtensions.cs index 27475a988..8d6e724ad 100644 --- a/src/Artemis.Core/Extensions/ProcessExtensions.cs +++ b/src/Artemis.Core/Extensions/ProcessExtensions.cs @@ -21,17 +21,17 @@ public static class ProcessExtensions { int capacity = 2000; StringBuilder builder = new(capacity); - IntPtr ptr = OpenProcess(ProcessAccessFlags.QueryLimitedInformation, false, p.Id); + nint ptr = OpenProcess(ProcessAccessFlags.QueryLimitedInformation, false, p.Id); if (!QueryFullProcessImageName(ptr, 0, builder, ref capacity)) return string.Empty; return builder.ToString(); } [DllImport("kernel32.dll", CharSet = CharSet.Unicode)] - private static extern bool QueryFullProcessImageName([In] IntPtr hProcess, [In] int dwFlags, [Out] StringBuilder lpExeName, ref int lpdwSize); + private static extern bool QueryFullProcessImageName([In] nint hProcess, [In] int dwFlags, [Out] StringBuilder lpExeName, ref int lpdwSize); [DllImport("kernel32.dll")] - private static extern IntPtr OpenProcess(ProcessAccessFlags processAccess, bool bInheritHandle, int processId); + private static extern nint OpenProcess(ProcessAccessFlags processAccess, bool bInheritHandle, int processId); [Flags] private enum ProcessAccessFlags : uint diff --git a/src/Artemis.Core/MVVM/CorePropertyChanged.cs b/src/Artemis.Core/MVVM/CorePropertyChanged.cs index 5e7b6b417..507d09a52 100644 --- a/src/Artemis.Core/MVVM/CorePropertyChanged.cs +++ b/src/Artemis.Core/MVVM/CorePropertyChanged.cs @@ -1,7 +1,7 @@ using System.Collections.Generic; using System.ComponentModel; using System.Runtime.CompilerServices; -using Artemis.Core.Properties; +using JetBrains.Annotations; namespace Artemis.Core; diff --git a/src/Artemis.Core/Plugins/Settings/PluginSetting.cs b/src/Artemis.Core/Plugins/Settings/PluginSetting.cs index a29022959..cd94e48d6 100644 --- a/src/Artemis.Core/Plugins/Settings/PluginSetting.cs +++ b/src/Artemis.Core/Plugins/Settings/PluginSetting.cs @@ -1,6 +1,4 @@ using System; -using System.Diagnostics.CodeAnalysis; -using Artemis.Core.Properties; using Artemis.Storage.Entities.Plugins; using Artemis.Storage.Repositories.Interfaces; using Newtonsoft.Json; @@ -36,9 +34,7 @@ public class PluginSetting : CorePropertyChanged, IPluginSetting /// /// The value of the setting /// - [AllowNull] - [CanBeNull] - public T Value + public T? Value { get => _value; set diff --git a/src/Artemis.Core/Properties/Annotations.cs b/src/Artemis.Core/Properties/Annotations.cs deleted file mode 100644 index c7e8987a1..000000000 --- a/src/Artemis.Core/Properties/Annotations.cs +++ /dev/null @@ -1,1382 +0,0 @@ -/* MIT License - -Copyright (c) 2016 JetBrains http://www.jetbrains.com - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. */ - -using System; - -#pragma warning disable 1591 -#pragma warning disable 8618 - -// ReSharper disable InheritdocConsiderUsage -// ReSharper disable UnusedMember.Global -// ReSharper disable MemberCanBePrivate.Global -// ReSharper disable UnusedAutoPropertyAccessor.Global -// ReSharper disable IntroduceOptionalParameters.Global -// ReSharper disable MemberCanBeProtected.Global -// ReSharper disable InconsistentNaming - -namespace Artemis.Core.Properties; - -/// -/// Indicates that the value of the marked element could be null sometimes, -/// so checking for null is required before its usage. -/// -/// -/// -/// [CanBeNull] object Test() => null; -/// -/// void UseTest() { -/// var p = Test(); -/// var s = p.ToString(); // Warning: Possible 'System.NullReferenceException' -/// } -/// -/// -[AttributeUsage( - AttributeTargets.Method | AttributeTargets.Parameter | AttributeTargets.Property | - AttributeTargets.Delegate | AttributeTargets.Field | AttributeTargets.Event | - AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.GenericParameter)] -public sealed class CanBeNullAttribute : Attribute -{ -} - -/// -/// Indicates that the value of the marked element can never be null. -/// -/// -/// -/// [NotNull] object Foo() { -/// return null; // Warning: Possible 'null' assignment -/// } -/// -/// -[AttributeUsage( - AttributeTargets.Method | AttributeTargets.Parameter | AttributeTargets.Property | - AttributeTargets.Delegate | AttributeTargets.Field | AttributeTargets.Event | - AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.GenericParameter)] -public sealed class NotNullAttribute : Attribute -{ -} - -/// -/// Can be applied to symbols of types derived from IEnumerable as well as to symbols of Task -/// and Lazy classes to indicate that the value of a collection item, of the Task.Result property -/// or of the Lazy.Value property can never be null. -/// -/// -/// -/// public void Foo([ItemNotNull]List<string> books) -/// { -/// foreach (var book in books) { -/// if (book != null) // Warning: Expression is always true -/// Console.WriteLine(book.ToUpper()); -/// } -/// } -/// -/// -[AttributeUsage( - AttributeTargets.Method | AttributeTargets.Parameter | AttributeTargets.Property | - AttributeTargets.Delegate | AttributeTargets.Field)] -public sealed class ItemNotNullAttribute : Attribute -{ -} - -/// -/// Can be applied to symbols of types derived from IEnumerable as well as to symbols of Task -/// and Lazy classes to indicate that the value of a collection item, of the Task.Result property -/// or of the Lazy.Value property can be null. -/// -/// -/// -/// public void Foo([ItemCanBeNull]List<string> books) -/// { -/// foreach (var book in books) -/// { -/// // Warning: Possible 'System.NullReferenceException' -/// Console.WriteLine(book.ToUpper()); -/// } -/// } -/// -/// -[AttributeUsage( - AttributeTargets.Method | AttributeTargets.Parameter | AttributeTargets.Property | - AttributeTargets.Delegate | AttributeTargets.Field)] -public sealed class ItemCanBeNullAttribute : Attribute -{ -} - -/// -/// Indicates that the marked method builds string by the format pattern and (optional) arguments. -/// The parameter, which contains the format string, should be given in constructor. The format string -/// should be in -like form. -/// -/// -/// -/// [StringFormatMethod("message")] -/// void ShowError(string message, params object[] args) { /* do something */ } -/// -/// void Foo() { -/// ShowError("Failed: {0}"); // Warning: Non-existing argument in format string -/// } -/// -/// -[AttributeUsage( - AttributeTargets.Constructor | AttributeTargets.Method | - AttributeTargets.Property | AttributeTargets.Delegate)] -public sealed class StringFormatMethodAttribute : Attribute -{ - /// - /// Specifies which parameter of an annotated method should be treated as the format string - /// - public StringFormatMethodAttribute([NotNull] string formatParameterName) - { - FormatParameterName = formatParameterName; - } - - [NotNull] - public string FormatParameterName { get; } -} - -/// -/// Use this annotation to specify a type that contains static or const fields -/// with values for the annotated property/field/parameter. -/// The specified type will be used to improve completion suggestions. -/// -/// -/// -/// namespace TestNamespace -/// { -/// public class Constants -/// { -/// public static int INT_CONST = 1; -/// public const string STRING_CONST = "1"; -/// } -/// -/// public class Class1 -/// { -/// [ValueProvider("TestNamespace.Constants")] public int myField; -/// public void Foo([ValueProvider("TestNamespace.Constants")] string str) { } -/// -/// public void Test() -/// { -/// Foo(/*try completion here*/);// -/// myField = /*try completion here*/ -/// } -/// } -/// } -/// -/// -[AttributeUsage( - AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.Field, - AllowMultiple = true)] -public sealed class ValueProviderAttribute : Attribute -{ - public ValueProviderAttribute([NotNull] string name) - { - Name = name; - } - - [NotNull] - public string Name { get; } -} - -/// -/// Indicates that the function argument should be a string literal and match one -/// of the parameters of the caller function. For example, ReSharper annotates -/// the parameter of . -/// -/// -/// -/// void Foo(string param) { -/// if (param == null) -/// throw new ArgumentNullException("par"); // Warning: Cannot resolve symbol -/// } -/// -/// -[AttributeUsage(AttributeTargets.Parameter)] -public sealed class InvokerParameterNameAttribute : Attribute -{ -} - -/// -/// Indicates that the method is contained in a type that implements -/// System.ComponentModel.INotifyPropertyChanged interface and this method -/// is used to notify that some property value changed. -/// -/// -/// The method should be non-static and conform to one of the supported signatures: -/// -/// -/// NotifyChanged(string) -/// -/// -/// NotifyChanged(params string[]) -/// -/// -/// NotifyChanged{T}(Expression{Func{T}}) -/// -/// -/// NotifyChanged{T,U}(Expression{Func{T,U}}) -/// -/// -/// SetProperty{T}(ref T, T, string) -/// -/// -/// -/// -/// -/// public class Foo : INotifyPropertyChanged { -/// public event PropertyChangedEventHandler PropertyChanged; -/// -/// [NotifyPropertyChangedInvocator] -/// protected virtual void NotifyChanged(string propertyName) { ... } -/// -/// string _name; -/// -/// public string Name { -/// get { return _name; } -/// set { _name = value; NotifyChanged("LastName"); /* Warning */ } -/// } -/// } -/// -/// Examples of generated notifications: -/// -/// -/// NotifyChanged("Property") -/// -/// -/// NotifyChanged(() => Property) -/// -/// -/// NotifyChanged((VM x) => x.Property) -/// -/// -/// SetProperty(ref myField, value, "Property") -/// -/// -/// -[AttributeUsage(AttributeTargets.Method)] -public sealed class NotifyPropertyChangedInvocatorAttribute : Attribute -{ - public NotifyPropertyChangedInvocatorAttribute() - { - } - - public NotifyPropertyChangedInvocatorAttribute([NotNull] string parameterName) - { - ParameterName = parameterName; - } - - [CanBeNull] - public string ParameterName { get; } -} - -/// -/// Describes dependency between method input and output. -/// -/// -///

Function Definition Table syntax:

-/// -/// FDT ::= FDTRow [;FDTRow]* -/// FDTRow ::= Input => Output | Output <= Input -/// Input ::= ParameterName: Value [, Input]* -/// Output ::= [ParameterName: Value]* {halt|stop|void|nothing|Value} -/// Value ::= true | false | null | notnull | canbenull -/// -/// If the method has a single input parameter, its name could be omitted.
-/// Using halt (or void/nothing, which is the same) for the method output -/// means that the method doesn't return normally (throws or terminates the process).
-/// Value canbenull is only applicable for output parameters.
-/// You can use multiple [ContractAnnotation] for each FDT row, or use single attribute -/// with rows separated by semicolon. There is no notion of order rows, all rows are checked -/// for applicability and applied per each program state tracked by the analysis engine.
-///
-/// -/// -/// -/// -/// [ContractAnnotation("=> halt")] -/// public void TerminationMethod() -/// -/// -/// -/// -/// [ContractAnnotation("null <= param:null")] // reverse condition syntax -/// public string GetName(string surname) -/// -/// -/// -/// -/// [ContractAnnotation("s:null => true")] -/// public bool IsNullOrEmpty(string s) // string.IsNullOrEmpty() -/// -/// -/// -/// -/// // A method that returns null if the parameter is null, -/// // and not null if the parameter is not null -/// [ContractAnnotation("null => null; notnull => notnull")] -/// public object Transform(object data) -/// -/// -/// -/// -/// [ContractAnnotation("=> true, result: notnull; => false, result: null")] -/// public bool TryParse(string s, out Person result) -/// -/// -/// -/// -[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] -public sealed class ContractAnnotationAttribute : Attribute -{ - public ContractAnnotationAttribute([NotNull] string contract) - : this(contract, false) - { - } - - public ContractAnnotationAttribute([NotNull] string contract, bool forceFullStates) - { - Contract = contract; - ForceFullStates = forceFullStates; - } - - [NotNull] - public string Contract { get; } - - public bool ForceFullStates { get; } -} - -/// -/// Indicates whether the marked element should be localized. -/// -/// -/// -/// [LocalizationRequiredAttribute(true)] -/// class Foo { -/// string str = "my string"; // Warning: Localizable string -/// } -/// -/// -[AttributeUsage(AttributeTargets.All)] -public sealed class LocalizationRequiredAttribute : Attribute -{ - public LocalizationRequiredAttribute() : this(true) - { - } - - public LocalizationRequiredAttribute(bool required) - { - Required = required; - } - - public bool Required { get; } -} - -/// -/// Indicates that the value of the marked type (or its derivatives) -/// cannot be compared using '==' or '!=' operators and Equals() -/// should be used instead. However, using '==' or '!=' for comparison -/// with null is always permitted. -/// -/// -/// -/// [CannotApplyEqualityOperator] -/// class NoEquality { } -/// -/// class UsesNoEquality { -/// void Test() { -/// var ca1 = new NoEquality(); -/// var ca2 = new NoEquality(); -/// if (ca1 != null) { // OK -/// bool condition = ca1 == ca2; // Warning -/// } -/// } -/// } -/// -/// -[AttributeUsage(AttributeTargets.Interface | AttributeTargets.Class | AttributeTargets.Struct)] -public sealed class CannotApplyEqualityOperatorAttribute : Attribute -{ -} - -/// -/// When applied to a target attribute, specifies a requirement for any type marked -/// with the target attribute to implement or inherit specific type or types. -/// -/// -/// -/// [BaseTypeRequired(typeof(IComponent)] // Specify requirement -/// class ComponentAttribute : Attribute { } -/// -/// [Component] // ComponentAttribute requires implementing IComponent interface -/// class MyComponent : IComponent { } -/// -/// -[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] -[BaseTypeRequired(typeof(Attribute))] -public sealed class BaseTypeRequiredAttribute : Attribute -{ - public BaseTypeRequiredAttribute([NotNull] Type baseType) - { - BaseType = baseType; - } - - [NotNull] - public Type BaseType { get; } -} - -/// -/// Indicates that the marked symbol is used implicitly (e.g. via reflection, in external library), -/// so this symbol will not be reported as unused (as well as by other usage inspections). -/// -[AttributeUsage(AttributeTargets.All, Inherited = false)] -public sealed class UsedImplicitlyAttribute : Attribute -{ - public UsedImplicitlyAttribute() - : this(ImplicitUseKindFlags.Default, ImplicitUseTargetFlags.Default) - { - } - - public UsedImplicitlyAttribute(ImplicitUseKindFlags useKindFlags) - : this(useKindFlags, ImplicitUseTargetFlags.Default) - { - } - - public UsedImplicitlyAttribute(ImplicitUseTargetFlags targetFlags) - : this(ImplicitUseKindFlags.Default, targetFlags) - { - } - - public UsedImplicitlyAttribute(ImplicitUseKindFlags useKindFlags, ImplicitUseTargetFlags targetFlags) - { - UseKindFlags = useKindFlags; - TargetFlags = targetFlags; - } - - public ImplicitUseKindFlags UseKindFlags { get; } - - public ImplicitUseTargetFlags TargetFlags { get; } -} - -/// -/// Can be applied to attributes, type parameters, and parameters of a type assignable from -/// . -/// When applied to an attribute, the decorated attribute behaves the same as . -/// When applied to a type parameter or to a parameter of type , indicates that the -/// corresponding type -/// is used implicitly. -/// -[AttributeUsage(AttributeTargets.Class | AttributeTargets.GenericParameter | AttributeTargets.Parameter)] -public sealed class MeansImplicitUseAttribute : Attribute -{ - public MeansImplicitUseAttribute() - : this(ImplicitUseKindFlags.Default, ImplicitUseTargetFlags.Default) - { - } - - public MeansImplicitUseAttribute(ImplicitUseKindFlags useKindFlags) - : this(useKindFlags, ImplicitUseTargetFlags.Default) - { - } - - public MeansImplicitUseAttribute(ImplicitUseTargetFlags targetFlags) - : this(ImplicitUseKindFlags.Default, targetFlags) - { - } - - public MeansImplicitUseAttribute(ImplicitUseKindFlags useKindFlags, ImplicitUseTargetFlags targetFlags) - { - UseKindFlags = useKindFlags; - TargetFlags = targetFlags; - } - - [UsedImplicitly] - public ImplicitUseKindFlags UseKindFlags { get; } - - [UsedImplicitly] - public ImplicitUseTargetFlags TargetFlags { get; } -} - -/// -/// Specify the details of implicitly used symbol when it is marked -/// with or . -/// -[Flags] -public enum ImplicitUseKindFlags -{ - Default = Access | Assign | InstantiatedWithFixedConstructorSignature, - - /// Only entity marked with attribute considered used. - Access = 1, - - /// Indicates implicit assignment to a member. - Assign = 2, - - /// - /// Indicates implicit instantiation of a type with fixed constructor signature. - /// That means any unused constructor parameters won't be reported as such. - /// - InstantiatedWithFixedConstructorSignature = 4, - - /// Indicates implicit instantiation of a type. - InstantiatedNoFixedConstructorSignature = 8 -} - -/// -/// Specify what is considered to be used implicitly when marked -/// with or . -/// -[Flags] -public enum ImplicitUseTargetFlags -{ - Default = Itself, - Itself = 1, - - /// Members of entity marked with attribute are considered used. - Members = 2, - - /// Entity marked with attribute and all its members considered used. - WithMembers = Itself | Members -} - -/// -/// This attribute is intended to mark publicly available API -/// which should not be removed and so is treated as used. -/// -[MeansImplicitUse(ImplicitUseTargetFlags.WithMembers)] -[AttributeUsage(AttributeTargets.All, Inherited = false)] -public sealed class PublicAPIAttribute : Attribute -{ - public PublicAPIAttribute() - { - } - - public PublicAPIAttribute([NotNull] string comment) - { - Comment = comment; - } - - [CanBeNull] - public string Comment { get; } -} - -/// -/// Tells code analysis engine if the parameter is completely handled when the invoked method is on stack. -/// If the parameter is a delegate, indicates that delegate is executed while the method is executed. -/// If the parameter is an enumerable, indicates that it is enumerated while the method is executed. -/// -[AttributeUsage(AttributeTargets.Parameter)] -public sealed class InstantHandleAttribute : Attribute -{ -} - -/// -/// Indicates that a method does not make any observable state changes. -/// The same as System.Diagnostics.Contracts.PureAttribute. -/// -/// -/// -/// [Pure] int Multiply(int x, int y) => x * y; -/// -/// void M() { -/// Multiply(123, 42); // Waring: Return value of pure method is not used -/// } -/// -/// -[AttributeUsage(AttributeTargets.Method)] -public sealed class PureAttribute : Attribute -{ -} - -/// -/// Indicates that the return value of the method invocation must be used. -/// -/// -/// Methods decorated with this attribute (in contrast to pure methods) might change state, -/// but make no sense without using their return value.
-/// Similarly to , this attribute -/// will help detecting usages of the method when the return value in not used. -/// Additionally, you can optionally specify a custom message, which will be used when showing warnings, e.g. -/// [MustUseReturnValue("Use the return value to...")]. -///
-[AttributeUsage(AttributeTargets.Method)] -public sealed class MustUseReturnValueAttribute : Attribute -{ - public MustUseReturnValueAttribute() - { - } - - public MustUseReturnValueAttribute([NotNull] string justification) - { - Justification = justification; - } - - [CanBeNull] - public string Justification { get; } -} - -/// -/// Indicates the type member or parameter of some type, that should be used instead of all other ways -/// to get the value of that type. This annotation is useful when you have some "context" value evaluated -/// and stored somewhere, meaning that all other ways to get this value must be consolidated with existing one. -/// -/// -/// -/// class Foo { -/// [ProvidesContext] IBarService _barService = ...; -/// -/// void ProcessNode(INode node) { -/// DoSomething(node, node.GetGlobalServices().Bar); -/// // ^ Warning: use value of '_barService' field -/// } -/// } -/// -/// -[AttributeUsage( - AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Parameter | AttributeTargets.Method | - AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.Struct | AttributeTargets.GenericParameter)] -public sealed class ProvidesContextAttribute : Attribute -{ -} - -/// -/// Indicates that a parameter is a path to a file or a folder within a web project. -/// Path can be relative or absolute, starting from web root (~). -/// -[AttributeUsage(AttributeTargets.Parameter)] -public sealed class PathReferenceAttribute : Attribute -{ - public PathReferenceAttribute() - { - } - - public PathReferenceAttribute([NotNull] [PathReference] string basePath) - { - BasePath = basePath; - } - - [CanBeNull] - public string BasePath { get; } -} - -/// -/// An extension method marked with this attribute is processed by code completion -/// as a 'Source Template'. When the extension method is completed over some expression, its source code -/// is automatically expanded like a template at call site. -/// -/// -/// Template method body can contain valid source code and/or special comments starting with '$'. -/// Text inside these comments is added as source code when the template is applied. Template parameters -/// can be used either as additional method parameters or as identifiers wrapped in two '$' signs. -/// Use the attribute to specify macros for parameters. -/// -/// -/// In this example, the 'forEach' method is a source template available over all values -/// of enumerable types, producing ordinary C# 'foreach' statement and placing caret inside block: -/// -/// [SourceTemplate] -/// public static void forEach<T>(this IEnumerable<T> xs) { -/// foreach (var x in xs) { -/// //$ $END$ -/// } -/// } -/// -/// -[AttributeUsage(AttributeTargets.Method)] -public sealed class SourceTemplateAttribute : Attribute -{ -} - -/// -/// Allows specifying a macro for a parameter of a source template. -/// -/// -/// You can apply the attribute on the whole method or on any of its additional parameters. The macro expression -/// is defined in the property. When applied on a method, the target -/// template parameter is defined in the property. To apply the macro silently -/// for the parameter, set the property value = -1. -/// -/// -/// Applying the attribute on a source template method: -/// -/// [SourceTemplate, Macro(Target = "item", Expression = "suggestVariableName()")] -/// public static void forEach<T>(this IEnumerable<T> collection) { -/// foreach (var item in collection) { -/// //$ $END$ -/// } -/// } -/// -/// Applying the attribute on a template method parameter: -/// -/// [SourceTemplate] -/// public static void something(this Entity x, [Macro(Expression = "guid()", Editable = -1)] string newguid) { -/// /*$ var $x$Id = "$newguid$" + x.ToString(); -/// x.DoSomething($x$Id); */ -/// } -/// -/// -[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Method, AllowMultiple = true)] -public sealed class MacroAttribute : Attribute -{ - /// - /// Allows specifying a macro that will be executed for a source template - /// parameter when the template is expanded. - /// - [CanBeNull] - public string Expression { get; set; } - - /// - /// Allows specifying which occurrence of the target parameter becomes editable when the template is deployed. - /// - /// - /// If the target parameter is used several times in the template, only one occurrence becomes editable; - /// other occurrences are changed synchronously. To specify the zero-based index of the editable occurrence, - /// use values >= 0. To make the parameter non-editable when the template is expanded, use -1. - /// - public int Editable { get; set; } - - /// - /// Identifies the target parameter of a source template if the - /// is applied on a template method. - /// - [CanBeNull] - public string Target { get; set; } -} - -[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = true)] -public sealed class AspMvcAreaMasterLocationFormatAttribute : Attribute -{ - public AspMvcAreaMasterLocationFormatAttribute([NotNull] string format) - { - Format = format; - } - - [NotNull] - public string Format { get; } -} - -[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = true)] -public sealed class AspMvcAreaPartialViewLocationFormatAttribute : Attribute -{ - public AspMvcAreaPartialViewLocationFormatAttribute([NotNull] string format) - { - Format = format; - } - - [NotNull] - public string Format { get; } -} - -[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = true)] -public sealed class AspMvcAreaViewLocationFormatAttribute : Attribute -{ - public AspMvcAreaViewLocationFormatAttribute([NotNull] string format) - { - Format = format; - } - - [NotNull] - public string Format { get; } -} - -[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = true)] -public sealed class AspMvcMasterLocationFormatAttribute : Attribute -{ - public AspMvcMasterLocationFormatAttribute([NotNull] string format) - { - Format = format; - } - - [NotNull] - public string Format { get; } -} - -[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = true)] -public sealed class AspMvcPartialViewLocationFormatAttribute : Attribute -{ - public AspMvcPartialViewLocationFormatAttribute([NotNull] string format) - { - Format = format; - } - - [NotNull] - public string Format { get; } -} - -[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = true)] -public sealed class AspMvcViewLocationFormatAttribute : Attribute -{ - public AspMvcViewLocationFormatAttribute([NotNull] string format) - { - Format = format; - } - - [NotNull] - public string Format { get; } -} - -/// -/// ASP.NET MVC attribute. If applied to a parameter, indicates that the parameter -/// is an MVC action. If applied to a method, the MVC action name is calculated -/// implicitly from the context. Use this attribute for custom wrappers similar to -/// System.Web.Mvc.Html.ChildActionExtensions.RenderAction(HtmlHelper, String). -/// -[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Method | AttributeTargets.Field | AttributeTargets.Property)] -public sealed class AspMvcActionAttribute : Attribute -{ - public AspMvcActionAttribute() - { - } - - public AspMvcActionAttribute([NotNull] string anonymousProperty) - { - AnonymousProperty = anonymousProperty; - } - - [CanBeNull] - public string AnonymousProperty { get; } -} - -/// -/// ASP.NET MVC attribute. Indicates that the marked parameter is an MVC area. -/// Use this attribute for custom wrappers similar to -/// System.Web.Mvc.Html.ChildActionExtensions.RenderAction(HtmlHelper, String). -/// -[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Field | AttributeTargets.Property)] -public sealed class AspMvcAreaAttribute : Attribute -{ - public AspMvcAreaAttribute() - { - } - - public AspMvcAreaAttribute([NotNull] string anonymousProperty) - { - AnonymousProperty = anonymousProperty; - } - - [CanBeNull] - public string AnonymousProperty { get; } -} - -/// -/// ASP.NET MVC attribute. If applied to a parameter, indicates that the parameter is -/// an MVC controller. If applied to a method, the MVC controller name is calculated -/// implicitly from the context. Use this attribute for custom wrappers similar to -/// System.Web.Mvc.Html.ChildActionExtensions.RenderAction(HtmlHelper, String, String). -/// -[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Method | AttributeTargets.Field | AttributeTargets.Property)] -public sealed class AspMvcControllerAttribute : Attribute -{ - public AspMvcControllerAttribute() - { - } - - public AspMvcControllerAttribute([NotNull] string anonymousProperty) - { - AnonymousProperty = anonymousProperty; - } - - [CanBeNull] - public string AnonymousProperty { get; } -} - -/// -/// ASP.NET MVC attribute. Indicates that the marked parameter is an MVC Master. Use this attribute -/// for custom wrappers similar to System.Web.Mvc.Controller.View(String, String). -/// -[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Field | AttributeTargets.Property)] -public sealed class AspMvcMasterAttribute : Attribute -{ -} - -/// -/// ASP.NET MVC attribute. Indicates that the marked parameter is an MVC model type. Use this attribute -/// for custom wrappers similar to System.Web.Mvc.Controller.View(String, Object). -/// -[AttributeUsage(AttributeTargets.Parameter)] -public sealed class AspMvcModelTypeAttribute : Attribute -{ -} - -/// -/// ASP.NET MVC attribute. If applied to a parameter, indicates that the parameter is an MVC -/// partial view. If applied to a method, the MVC partial view name is calculated implicitly -/// from the context. Use this attribute for custom wrappers similar to -/// System.Web.Mvc.Html.RenderPartialExtensions.RenderPartial(HtmlHelper, String). -/// -[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Method | AttributeTargets.Field | AttributeTargets.Property)] -public sealed class AspMvcPartialViewAttribute : Attribute -{ -} - -/// -/// ASP.NET MVC attribute. Allows disabling inspections for MVC views within a class or a method. -/// -[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)] -public sealed class AspMvcSuppressViewErrorAttribute : Attribute -{ -} - -/// -/// ASP.NET MVC attribute. Indicates that a parameter is an MVC display template. -/// Use this attribute for custom wrappers similar to -/// System.Web.Mvc.Html.DisplayExtensions.DisplayForModel(HtmlHelper, String). -/// -[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Field | AttributeTargets.Property)] -public sealed class AspMvcDisplayTemplateAttribute : Attribute -{ -} - -/// -/// ASP.NET MVC attribute. Indicates that the marked parameter is an MVC editor template. -/// Use this attribute for custom wrappers similar to -/// System.Web.Mvc.Html.EditorExtensions.EditorForModel(HtmlHelper, String). -/// -[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Field | AttributeTargets.Property)] -public sealed class AspMvcEditorTemplateAttribute : Attribute -{ -} - -/// -/// ASP.NET MVC attribute. Indicates that the marked parameter is an MVC template. -/// Use this attribute for custom wrappers similar to -/// System.ComponentModel.DataAnnotations.UIHintAttribute(System.String). -/// -[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Field | AttributeTargets.Property)] -public sealed class AspMvcTemplateAttribute : Attribute -{ -} - -/// -/// ASP.NET MVC attribute. If applied to a parameter, indicates that the parameter -/// is an MVC view component. If applied to a method, the MVC view name is calculated implicitly -/// from the context. Use this attribute for custom wrappers similar to -/// System.Web.Mvc.Controller.View(Object). -/// -[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Method | AttributeTargets.Field | AttributeTargets.Property)] -public sealed class AspMvcViewAttribute : Attribute -{ -} - -/// -/// ASP.NET MVC attribute. If applied to a parameter, indicates that the parameter -/// is an MVC view component name. -/// -[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Field | AttributeTargets.Property)] -public sealed class AspMvcViewComponentAttribute : Attribute -{ -} - -/// -/// ASP.NET MVC attribute. If applied to a parameter, indicates that the parameter -/// is an MVC view component view. If applied to a method, the MVC view component view name is default. -/// -[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Method | AttributeTargets.Field | AttributeTargets.Property)] -public sealed class AspMvcViewComponentViewAttribute : Attribute -{ -} - -/// -/// ASP.NET MVC attribute. When applied to a parameter of an attribute, -/// indicates that this parameter is an MVC action name. -/// -/// -/// -/// [ActionName("Foo")] -/// public ActionResult Login(string returnUrl) { -/// ViewBag.ReturnUrl = Url.Action("Foo"); // OK -/// return RedirectToAction("Bar"); // Error: Cannot resolve action -/// } -/// -/// -[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Property)] -public sealed class AspMvcActionSelectorAttribute : Attribute -{ -} - -[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.Field)] -public sealed class HtmlElementAttributesAttribute : Attribute -{ - public HtmlElementAttributesAttribute() - { - } - - public HtmlElementAttributesAttribute([NotNull] string name) - { - Name = name; - } - - [CanBeNull] - public string Name { get; } -} - -[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Field | AttributeTargets.Property)] -public sealed class HtmlAttributeValueAttribute : Attribute -{ - public HtmlAttributeValueAttribute([NotNull] string name) - { - Name = name; - } - - [NotNull] - public string Name { get; } -} - -/// -/// Razor attribute. Indicates that the marked parameter or method is a Razor section. -/// Use this attribute for custom wrappers similar to -/// System.Web.WebPages.WebPageBase.RenderSection(String). -/// -[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Method)] -public sealed class RazorSectionAttribute : Attribute -{ -} - -/// -/// Indicates how method, constructor invocation, or property access -/// over collection type affects the contents of the collection. -/// Use to specify the access type. -/// -/// -/// Using this attribute only makes sense if all collection methods are marked with this attribute. -/// -/// -/// -/// public class MyStringCollection : List<string> -/// { -/// [CollectionAccess(CollectionAccessType.Read)] -/// public string GetFirstString() -/// { -/// return this.ElementAt(0); -/// } -/// } -/// class Test -/// { -/// public void Foo() -/// { -/// // Warning: Contents of the collection is never updated -/// var col = new MyStringCollection(); -/// string x = col.GetFirstString(); -/// } -/// } -/// -/// -[AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Property)] -public sealed class CollectionAccessAttribute : Attribute -{ - public CollectionAccessAttribute(CollectionAccessType collectionAccessType) - { - CollectionAccessType = collectionAccessType; - } - - public CollectionAccessType CollectionAccessType { get; } -} - -/// -/// Provides a value for the to define -/// how the collection method invocation affects the contents of the collection. -/// -[Flags] -public enum CollectionAccessType -{ - /// Method does not use or modify content of the collection. - None = 0, - - /// Method only reads content of the collection but does not modify it. - Read = 1, - - /// Method can change content of the collection but does not add new elements. - ModifyExistingContent = 2, - - /// Method can add new elements to the collection. - UpdatedContent = ModifyExistingContent | 4 -} - -/// -/// Indicates that the marked method is assertion method, i.e. it halts the control flow if -/// one of the conditions is satisfied. To set the condition, mark one of the parameters with -/// attribute. -/// -[AttributeUsage(AttributeTargets.Method)] -public sealed class AssertionMethodAttribute : Attribute -{ -} - -/// -/// Indicates the condition parameter of the assertion method. The method itself should be -/// marked by attribute. The mandatory argument of -/// the attribute is the assertion type. -/// -[AttributeUsage(AttributeTargets.Parameter)] -public sealed class AssertionConditionAttribute : Attribute -{ - public AssertionConditionAttribute(AssertionConditionType conditionType) - { - ConditionType = conditionType; - } - - public AssertionConditionType ConditionType { get; } -} - -/// -/// Specifies assertion type. If the assertion method argument satisfies the condition, -/// then the execution continues. Otherwise, execution is assumed to be halted. -/// -public enum AssertionConditionType -{ - /// Marked parameter should be evaluated to true. - IS_TRUE = 0, - - /// Marked parameter should be evaluated to false. - IS_FALSE = 1, - - /// Marked parameter should be evaluated to null value. - IS_NULL = 2, - - /// Marked parameter should be evaluated to not null value. - IS_NOT_NULL = 3 -} - -/// -/// Indicates that the marked method unconditionally terminates control flow execution. -/// For example, it could unconditionally throw exception. -/// -[Obsolete("Use [ContractAnnotation('=> halt')] instead")] -[AttributeUsage(AttributeTargets.Method)] -public sealed class TerminatesProgramAttribute : Attribute -{ -} - -/// -/// Indicates that method is pure LINQ method, with postponed enumeration (like Enumerable.Select, -/// .Where). This annotation allows inference of [InstantHandle] annotation for parameters -/// of delegate type by analyzing LINQ method chains. -/// -[AttributeUsage(AttributeTargets.Method)] -public sealed class LinqTunnelAttribute : Attribute -{ -} - -/// -/// Indicates that IEnumerable passed as a parameter is not enumerated. -/// Use this annotation to suppress the 'Possible multiple enumeration of IEnumerable' inspection. -/// -/// -/// -/// static void ThrowIfNull<T>([NoEnumeration] T v, string n) where T : class -/// { -/// // custom check for null but no enumeration -/// } -/// -/// void Foo(IEnumerable<string> values) -/// { -/// ThrowIfNull(values, nameof(values)); -/// var x = values.ToList(); // No warnings about multiple enumeration -/// } -/// -/// -[AttributeUsage(AttributeTargets.Parameter)] -public sealed class NoEnumerationAttribute : Attribute -{ -} - -/// -/// Indicates that the marked parameter is a regular expression pattern. -/// -[AttributeUsage(AttributeTargets.Parameter)] -public sealed class RegexPatternAttribute : Attribute -{ -} - -/// -/// Prevents the Member Reordering feature from tossing members of the marked class. -/// -/// -/// The attribute must be mentioned in your member reordering patterns. -/// -[AttributeUsage( - AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.Struct | AttributeTargets.Enum)] -public sealed class NoReorderAttribute : Attribute -{ -} - -/// -/// XAML attribute. Indicates the type that has ItemsSource property and should be treated -/// as ItemsControl-derived type, to enable inner items DataContext type resolve. -/// -[AttributeUsage(AttributeTargets.Class)] -public sealed class XamlItemsControlAttribute : Attribute -{ -} - -/// -/// XAML attribute. Indicates the property of some BindingBase-derived type, that -/// is used to bind some item of ItemsControl-derived type. This annotation will -/// enable the DataContext type resolve for XAML bindings for such properties. -/// -/// -/// Property should have the tree ancestor of the ItemsControl type or -/// marked with the attribute. -/// -[AttributeUsage(AttributeTargets.Property)] -public sealed class XamlItemBindingOfItemsControlAttribute : Attribute -{ -} - -[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] -public sealed class AspChildControlTypeAttribute : Attribute -{ - public AspChildControlTypeAttribute([NotNull] string tagName, [NotNull] Type controlType) - { - TagName = tagName; - ControlType = controlType; - } - - [NotNull] - public string TagName { get; } - - [NotNull] - public Type ControlType { get; } -} - -[AttributeUsage(AttributeTargets.Property | AttributeTargets.Method)] -public sealed class AspDataFieldAttribute : Attribute -{ -} - -[AttributeUsage(AttributeTargets.Property | AttributeTargets.Method)] -public sealed class AspDataFieldsAttribute : Attribute -{ -} - -[AttributeUsage(AttributeTargets.Property)] -public sealed class AspMethodPropertyAttribute : Attribute -{ -} - -[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] -public sealed class AspRequiredAttributeAttribute : Attribute -{ - public AspRequiredAttributeAttribute([NotNull] string attribute) - { - Attribute = attribute; - } - - [NotNull] - public string Attribute { get; } -} - -[AttributeUsage(AttributeTargets.Property)] -public sealed class AspTypePropertyAttribute : Attribute -{ - public AspTypePropertyAttribute(bool createConstructorReferences) - { - CreateConstructorReferences = createConstructorReferences; - } - - public bool CreateConstructorReferences { get; } -} - -[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] -public sealed class RazorImportNamespaceAttribute : Attribute -{ - public RazorImportNamespaceAttribute([NotNull] string name) - { - Name = name; - } - - [NotNull] - public string Name { get; } -} - -[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] -public sealed class RazorInjectionAttribute : Attribute -{ - public RazorInjectionAttribute([NotNull] string type, [NotNull] string fieldName) - { - Type = type; - FieldName = fieldName; - } - - [NotNull] - public string Type { get; } - - [NotNull] - public string FieldName { get; } -} - -[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] -public sealed class RazorDirectiveAttribute : Attribute -{ - public RazorDirectiveAttribute([NotNull] string directive) - { - Directive = directive; - } - - [NotNull] - public string Directive { get; } -} - -[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] -public sealed class RazorPageBaseTypeAttribute : Attribute -{ - public RazorPageBaseTypeAttribute([NotNull] string baseType) - { - BaseType = baseType; - } - - public RazorPageBaseTypeAttribute([NotNull] string baseType, string pageName) - { - BaseType = baseType; - PageName = pageName; - } - - [NotNull] - public string BaseType { get; } - - [CanBeNull] - public string PageName { get; } -} - -[AttributeUsage(AttributeTargets.Method)] -public sealed class RazorHelperCommonAttribute : Attribute -{ -} - -[AttributeUsage(AttributeTargets.Property)] -public sealed class RazorLayoutAttribute : Attribute -{ -} - -[AttributeUsage(AttributeTargets.Method)] -public sealed class RazorWriteLiteralMethodAttribute : Attribute -{ -} - -[AttributeUsage(AttributeTargets.Method)] -public sealed class RazorWriteMethodAttribute : Attribute -{ -} - -[AttributeUsage(AttributeTargets.Parameter)] -public sealed class RazorWriteMethodParameterAttribute : Attribute -{ -} \ No newline at end of file diff --git a/src/Artemis.Core/Services/Interfaces/IPluginManagementService.cs b/src/Artemis.Core/Services/Interfaces/IPluginManagementService.cs index 209158529..8e0faf564 100644 --- a/src/Artemis.Core/Services/Interfaces/IPluginManagementService.cs +++ b/src/Artemis.Core/Services/Interfaces/IPluginManagementService.cs @@ -127,6 +127,13 @@ public interface IPluginManagementService : IArtemisService, IDisposable /// If the current call stack contains a plugin, the plugin. Otherwise null Plugin? GetCallingPlugin(); + /// + /// Returns the plugin that threw the provided exception. + /// + /// + /// If the exception was thrown by a plugin, the plugin. Otherwise null + Plugin? GetPluginFromException(Exception exception); + /// /// Gets the plugin that defined the specified device /// diff --git a/src/Artemis.Core/Services/PluginManagementService.cs b/src/Artemis.Core/Services/PluginManagementService.cs index 06b9b6368..c03aec7bb 100644 --- a/src/Artemis.Core/Services/PluginManagementService.cs +++ b/src/Artemis.Core/Services/PluginManagementService.cs @@ -192,7 +192,19 @@ internal class PluginManagementService : IPluginManagementService public Plugin? GetCallingPlugin() { - StackTrace stackTrace = new(); // get call stack + return GetPluginFromStackTrace(new StackTrace()); + } + + public Plugin? GetPluginFromException(Exception exception) + { + if (exception is ArtemisPluginException pluginException && pluginException.Plugin != null) + return pluginException.Plugin; + + return GetPluginFromStackTrace(new StackTrace(exception)); + } + + private Plugin? GetPluginFromStackTrace(StackTrace stackTrace) + { StackFrame[] stackFrames = stackTrace.GetFrames(); // get method calls (frames) foreach (StackFrame stackFrame in stackFrames) diff --git a/src/Artemis.Core/Services/WebServer/WebModuleRegistration.cs b/src/Artemis.Core/Services/WebServer/WebModuleRegistration.cs index 450ac7435..270a5ec4d 100644 --- a/src/Artemis.Core/Services/WebServer/WebModuleRegistration.cs +++ b/src/Artemis.Core/Services/WebServer/WebModuleRegistration.cs @@ -1,6 +1,5 @@ using System; using EmbedIO; -using DryIoc; namespace Artemis.Core.Services; diff --git a/src/Artemis.Core/VisualScripting/NodeScript.cs b/src/Artemis.Core/VisualScripting/NodeScript.cs index 7a02555ac..7672f3504 100644 --- a/src/Artemis.Core/VisualScripting/NodeScript.cs +++ b/src/Artemis.Core/VisualScripting/NodeScript.cs @@ -4,8 +4,8 @@ using System.Collections.ObjectModel; using System.Linq; using Artemis.Core.Events; using Artemis.Core.Internal; -using Artemis.Core.Properties; using Artemis.Storage.Entities.Profile.Nodes; +using JetBrains.Annotations; namespace Artemis.Core; diff --git a/src/Artemis.Storage/Artemis.Storage.csproj b/src/Artemis.Storage/Artemis.Storage.csproj index 2e7bb99ae..6ccd74e0d 100644 --- a/src/Artemis.Storage/Artemis.Storage.csproj +++ b/src/Artemis.Storage/Artemis.Storage.csproj @@ -1,12 +1,12 @@  - net6.0 + net7.0 false x64 - - + + \ No newline at end of file diff --git a/src/Artemis.Storage/Entities/General/ReleaseEntity.cs b/src/Artemis.Storage/Entities/General/ReleaseEntity.cs index 7c517ff79..b3f39fb64 100644 --- a/src/Artemis.Storage/Entities/General/ReleaseEntity.cs +++ b/src/Artemis.Storage/Entities/General/ReleaseEntity.cs @@ -5,7 +5,7 @@ namespace Artemis.Storage.Entities.General; public class ReleaseEntity { public Guid Id { get; set; } - + public string Version { get; set; } public DateTimeOffset? InstalledAt { get; set; } } \ No newline at end of file diff --git a/src/Artemis.Storage/Entities/Profile/LedEntity.cs b/src/Artemis.Storage/Entities/Profile/LedEntity.cs index 1b479ef69..be4536471 100644 --- a/src/Artemis.Storage/Entities/Profile/LedEntity.cs +++ b/src/Artemis.Storage/Entities/Profile/LedEntity.cs @@ -5,6 +5,11 @@ namespace Artemis.Storage.Entities.Profile; public class LedEntity { + public string LedName { get; set; } + public string DeviceIdentifier { get; set; } + + public int? PhysicalLayout { get; set; } + #region LedEntityEqualityComparer private sealed class LedEntityEqualityComparer : IEqualityComparer @@ -31,9 +36,4 @@ public class LedEntity public static IEqualityComparer LedEntityComparer { get; } = new LedEntityEqualityComparer(); #endregion - - public string LedName { get; set; } - public string DeviceIdentifier { get; set; } - - public int? PhysicalLayout { get; set; } } \ No newline at end of file diff --git a/src/Artemis.Storage/Migrations/M0021GradientNodes.cs b/src/Artemis.Storage/Migrations/M0021GradientNodes.cs index c89801fab..dba1e8956 100644 --- a/src/Artemis.Storage/Migrations/M0021GradientNodes.cs +++ b/src/Artemis.Storage/Migrations/M0021GradientNodes.cs @@ -51,7 +51,7 @@ public class M0021GradientNodes : IStorageMigration TargetType = "ColorGradient", TargetNode = gradientNode.Id, TargetPinCollectionId = -1, - TargetPinId = 0, + TargetPinId = 0 }); // Move the exit node to the right @@ -59,6 +59,18 @@ public class M0021GradientNodes : IStorageMigration exitNode.Y += 30; } + private void MigrateDataBinding(PropertyGroupEntity propertyGroup) + { + foreach (PropertyGroupEntity propertyGroupPropertyGroup in propertyGroup.PropertyGroups) + MigrateDataBinding(propertyGroupPropertyGroup); + + foreach (PropertyEntity property in propertyGroup.Properties) + { + if (property.Value.StartsWith("[{\"Color\":\"") && property.DataBinding?.NodeScript != null && property.DataBinding.IsEnabled) + MigrateDataBinding(property); + } + } + public int UserVersion => 21; public void Apply(LiteRepository repository) @@ -73,16 +85,4 @@ public class M0021GradientNodes : IStorageMigration repository.Update(profileEntity); } } - - private void MigrateDataBinding(PropertyGroupEntity propertyGroup) - { - foreach (PropertyGroupEntity propertyGroupPropertyGroup in propertyGroup.PropertyGroups) - MigrateDataBinding(propertyGroupPropertyGroup); - - foreach (PropertyEntity property in propertyGroup.Properties) - { - if (property.Value.StartsWith("[{\"Color\":\"") && property.DataBinding?.NodeScript != null && property.DataBinding.IsEnabled) - MigrateDataBinding(property); - } - } } \ No newline at end of file diff --git a/src/Artemis.Storage/Migrations/M0022TransitionNodes.cs b/src/Artemis.Storage/Migrations/M0022TransitionNodes.cs index 5341371da..3258a6d10 100644 --- a/src/Artemis.Storage/Migrations/M0022TransitionNodes.cs +++ b/src/Artemis.Storage/Migrations/M0022TransitionNodes.cs @@ -22,7 +22,7 @@ public class M0022TransitionNodes : IStorageMigration else if (node.Type == "ColorGradientEasingNode") node.Type = "ColorGradientTransitionNode"; else if (node.Type == "SKColorEasingNode") - node.Type = "SKColorTransitionNode"; + node.Type = "SKColorTransitionNode"; else if (node.Type == "EasingTypeNode") node.Type = "EasingFunctionNode"; } diff --git a/src/Artemis.Storage/Repositories/QueuedActionRepository.cs b/src/Artemis.Storage/Repositories/QueuedActionRepository.cs index f5c83cd0e..cf2bc862d 100644 --- a/src/Artemis.Storage/Repositories/QueuedActionRepository.cs +++ b/src/Artemis.Storage/Repositories/QueuedActionRepository.cs @@ -46,7 +46,7 @@ public class QueuedActionRepository : IQueuedActionRepository { return _repository.Query().Where(q => q.Type == type).Count() > 0; } - + /// public void ClearByType(string type) { diff --git a/src/Artemis.UI.Linux/App.axaml.cs b/src/Artemis.UI.Linux/App.axaml.cs index 7040f8183..1a6cd64a5 100644 --- a/src/Artemis.UI.Linux/App.axaml.cs +++ b/src/Artemis.UI.Linux/App.axaml.cs @@ -5,7 +5,7 @@ using Avalonia; using Avalonia.Controls; using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Markup.Xaml; -using Avalonia.Threading; +using Avalonia.ReactiveUI; using DryIoc; using ReactiveUI; diff --git a/src/Artemis.UI.Linux/Artemis.UI.Linux.csproj b/src/Artemis.UI.Linux/Artemis.UI.Linux.csproj index 3d48d5686..210637896 100644 --- a/src/Artemis.UI.Linux/Artemis.UI.Linux.csproj +++ b/src/Artemis.UI.Linux/Artemis.UI.Linux.csproj @@ -1,7 +1,7 @@ WinExe - net6.0 + net7.0 enable x64 x64 @@ -16,12 +16,12 @@
- - + + - - - + + + diff --git a/src/Artemis.UI.MacOS/App.axaml.cs b/src/Artemis.UI.MacOS/App.axaml.cs index f1aed23d3..0d81b318d 100644 --- a/src/Artemis.UI.MacOS/App.axaml.cs +++ b/src/Artemis.UI.MacOS/App.axaml.cs @@ -1,7 +1,7 @@ using Avalonia; using Avalonia.Controls; using Avalonia.Markup.Xaml; -using Avalonia.Threading; +using Avalonia.ReactiveUI; using DryIoc; using ReactiveUI; diff --git a/src/Artemis.UI.MacOS/Artemis.UI.MacOS.csproj b/src/Artemis.UI.MacOS/Artemis.UI.MacOS.csproj index 65ef347d2..000fe864e 100644 --- a/src/Artemis.UI.MacOS/Artemis.UI.MacOS.csproj +++ b/src/Artemis.UI.MacOS/Artemis.UI.MacOS.csproj @@ -1,7 +1,7 @@  WinExe - net6.0 + net7.0 enable x64 x64 @@ -15,12 +15,12 @@ - - + + - - - + + + diff --git a/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj b/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj index 047d9906f..4ae1e9f7c 100644 --- a/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj +++ b/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj @@ -1,7 +1,7 @@  Library - net6.0 + net7.0 enable bin\ x64 @@ -10,18 +10,18 @@ - + - - - - - - - - - - + + + + + + + + + + diff --git a/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj.DotSettings b/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj.DotSettings index 22557dc59..4dc50ad43 100644 --- a/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj.DotSettings +++ b/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj.DotSettings @@ -1,4 +1,5 @@ - + True True True diff --git a/src/Artemis.UI.Shared/Behaviors/LostFocusNumericUpDownBindingBehavior.cs b/src/Artemis.UI.Shared/Behaviors/LostFocusNumericUpDownBindingBehavior.cs index 23e2bdbdb..1b6da7178 100644 --- a/src/Artemis.UI.Shared/Behaviors/LostFocusNumericUpDownBindingBehavior.cs +++ b/src/Artemis.UI.Shared/Behaviors/LostFocusNumericUpDownBindingBehavior.cs @@ -15,7 +15,7 @@ public class LostFocusNumericUpDownBindingBehavior : Behavior /// /// Gets or sets the value of the binding. /// - public static readonly StyledProperty ValueProperty = AvaloniaProperty.Register( + public static readonly StyledProperty ValueProperty = AvaloniaProperty.Register( nameof(Value), defaultBindingMode: BindingMode.TwoWay); static LostFocusNumericUpDownBindingBehavior() @@ -26,7 +26,7 @@ public class LostFocusNumericUpDownBindingBehavior : Behavior /// /// Gets or sets the value of the binding. /// - public double Value + public decimal? Value { get => GetValue(ValueProperty); set => SetValue(ValueProperty, value); diff --git a/src/Artemis.UI.Shared/Controls/ArtemisIcon.axaml.cs b/src/Artemis.UI.Shared/Controls/ArtemisIcon.axaml.cs index 1e3e47a1d..e403d0c93 100644 --- a/src/Artemis.UI.Shared/Controls/ArtemisIcon.axaml.cs +++ b/src/Artemis.UI.Shared/Controls/ArtemisIcon.axaml.cs @@ -2,12 +2,12 @@ using System; using System.Text.RegularExpressions; using Avalonia; using Avalonia.Controls; +using Avalonia.Controls.Documents; using Avalonia.Layout; using Avalonia.LogicalTree; using Avalonia.Markup.Xaml; using Avalonia.Media; using Avalonia.Media.Imaging; -using Avalonia.Visuals.Media.Imaging; using Material.Icons; using Material.Icons.Avalonia; @@ -16,9 +16,9 @@ namespace Artemis.UI.Shared; /// /// Represents a control that can display an arbitrary kind of icon. /// -public class ArtemisIcon : UserControl +public partial class ArtemisIcon : UserControl { - private static readonly Regex _imageRegex = new(@"[\/.](gif|jpg|jpeg|tiff|png)$", RegexOptions.Compiled); + private static readonly Regex ImageRegex = new(@"[\/.](gif|jpg|jpeg|tiff|png)$", RegexOptions.Compiled); /// /// Creates a new instance of the class. @@ -28,12 +28,7 @@ public class ArtemisIcon : UserControl InitializeComponent(); DetachedFromLogicalTree += OnDetachedFromLogicalTree; LayoutUpdated += OnLayoutUpdated; - } - - private static void IconChanging(IAvaloniaObject sender, bool before) - { - if (before) - ((ArtemisIcon) sender).Update(); + PropertyChanged += OnPropertyChanged; } private void Update() @@ -54,7 +49,7 @@ public class ArtemisIcon : UserControl Content = new MaterialIcon {Kind = parsedIcon, Width = Bounds.Width, Height = Bounds.Height}; } // An URI pointing to an image - else if (_imageRegex.IsMatch(iconString)) + else if (ImageRegex.IsMatch(iconString)) { if (!Fill) Content = new Image @@ -66,7 +61,7 @@ public class ArtemisIcon : UserControl else Content = new Border { - Background = TextBlock.GetForeground(this), + Background = TextElement.GetForeground(this), VerticalAlignment = VerticalAlignment.Stretch, HorizontalAlignment = HorizontalAlignment.Stretch, OpacityMask = new ImageBrush(new Bitmap(iconString)) {BitmapInterpolationMode = BitmapInterpolationMode.MediumQuality} @@ -92,6 +87,12 @@ public class ArtemisIcon : UserControl contentControl.Height = Bounds.Height; } } + + private void OnPropertyChanged(object? sender, AvaloniaPropertyChangedEventArgs e) + { + if (e.Property == IconProperty || e.Property == FillProperty) + Update(); + } private void OnDetachedFromLogicalTree(object? sender, LogicalTreeAttachmentEventArgs e) { @@ -99,19 +100,13 @@ public class ArtemisIcon : UserControl disposable.Dispose(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } - #region Properties /// /// Gets or sets the currently displayed icon as either a or an /// pointing to an SVG /// - public static readonly StyledProperty IconProperty = - AvaloniaProperty.Register(nameof(Icon), notifying: IconChanging); + public static readonly StyledProperty IconProperty = AvaloniaProperty.Register(nameof(Icon)); /// @@ -128,8 +123,7 @@ public class ArtemisIcon : UserControl /// Gets or sets a boolean indicating whether or not the icon should be filled in with the primary text color of the /// theme /// - public static readonly StyledProperty FillProperty = - AvaloniaProperty.Register(nameof(Icon), false, notifying: IconChanging); + public static readonly StyledProperty FillProperty = AvaloniaProperty.Register(nameof(Icon)); /// /// Gets or sets a boolean indicating whether or not the icon should be filled in with the primary text color of the diff --git a/src/Artemis.UI.Shared/Controls/DataModelPicker/DataModelPickerButton.cs b/src/Artemis.UI.Shared/Controls/DataModelPicker/DataModelPickerButton.cs index 1535569cc..eb8ab30a4 100644 --- a/src/Artemis.UI.Shared/Controls/DataModelPicker/DataModelPickerButton.cs +++ b/src/Artemis.UI.Shared/Controls/DataModelPicker/DataModelPickerButton.cs @@ -46,8 +46,8 @@ public class DataModelPickerButton : TemplatedControl /// /// Gets or sets the desired flyout placement. /// - public static readonly StyledProperty PlacementProperty = - AvaloniaProperty.Register(nameof(Placement)); + public static readonly StyledProperty PlacementProperty = + AvaloniaProperty.Register(nameof(Placement)); /// /// Gets or sets data model path. @@ -133,7 +133,7 @@ public class DataModelPickerButton : TemplatedControl /// /// Gets or sets the desired flyout placement. /// - public FlyoutPlacementMode Placement + public PlacementMode Placement { get => GetValue(PlacementProperty); set => SetValue(PlacementProperty, value); diff --git a/src/Artemis.UI.Shared/Controls/DeviceVisualizer.cs b/src/Artemis.UI.Shared/Controls/DeviceVisualizer.cs index 1632f25a7..b93053583 100644 --- a/src/Artemis.UI.Shared/Controls/DeviceVisualizer.cs +++ b/src/Artemis.UI.Shared/Controls/DeviceVisualizer.cs @@ -12,10 +12,7 @@ using Avalonia.Input; using Avalonia.LogicalTree; using Avalonia.Media; using Avalonia.Media.Imaging; -using Avalonia.Platform; -using Avalonia.Rendering; using Avalonia.Threading; -using Avalonia.Visuals.Media.Imaging; namespace Artemis.UI.Shared; @@ -41,12 +38,14 @@ public class DeviceVisualizer : Control _deviceVisualizerLeds = new List(); PointerReleased += OnPointerReleased; + PropertyChanged += OnPropertyChanged; } + /// public override void Render(DrawingContext drawingContext) { - if (Device == null) + if (Device == null || _deviceBounds.Width == 0 || _deviceBounds.Height == 0 || _loading) return; // Determine the scale required to fit the desired size of the control @@ -57,11 +56,11 @@ public class DeviceVisualizer : Control { // Scale the visualization in the desired bounding box if (Bounds.Width > 0 && Bounds.Height > 0) - boundsPush = drawingContext.PushPreTransform(Matrix.CreateScale(scale, scale)); + boundsPush = drawingContext.PushTransform(Matrix.CreateScale(scale, scale)); // Apply device rotation - using DrawingContext.PushedState translationPush = drawingContext.PushPreTransform(Matrix.CreateTranslation(0 - _deviceBounds.Left, 0 - _deviceBounds.Top)); - using DrawingContext.PushedState rotationPush = drawingContext.PushPreTransform(Matrix.CreateRotation(Matrix.ToRadians(Device.Rotation))); + using DrawingContext.PushedState translationPush = drawingContext.PushTransform(Matrix.CreateTranslation(0 - _deviceBounds.Left, 0 - _deviceBounds.Top)); + using DrawingContext.PushedState rotationPush = drawingContext.PushTransform(Matrix.CreateRotation(Matrix.ToRadians(Device.Rotation))); // Render device and LED images if (_deviceImage != null) @@ -78,7 +77,7 @@ public class DeviceVisualizer : Control lock (_deviceVisualizerLeds) { // Apply device scale - using DrawingContext.PushedState scalePush = drawingContext.PushPreTransform(Matrix.CreateScale(Device.Scale, Device.Scale)); + using DrawingContext.PushedState scalePush = drawingContext.PushTransform(Matrix.CreateScale(Device.Scale, Device.Scale)); foreach (DeviceVisualizerLed deviceVisualizerLed in _deviceVisualizerLeds) deviceVisualizerLed.RenderGeometry(drawingContext, false); } @@ -123,7 +122,7 @@ public class DeviceVisualizer : Control private Rect MeasureDevice() { if (Device == null) - return Rect.Empty; + return new Rect(); Rect deviceRect = new(0, 0, Device.RgbDevice.ActualSize.Width, Device.RgbDevice.ActualSize.Height); Geometry geometry = new RectangleGeometry(deviceRect); @@ -155,6 +154,12 @@ public class DeviceVisualizer : Control OnClicked(e); } + private void OnPropertyChanged(object? sender, AvaloniaPropertyChangedEventArgs e) + { + if (e.Property == DeviceProperty) + SetupForDevice(); + } + private void DevicePropertyChanged(object? sender, PropertyChangedEventArgs e) { Dispatcher.UIThread.Post(SetupForDevice, DispatcherPriority.Background); @@ -171,13 +176,7 @@ public class DeviceVisualizer : Control /// Gets or sets the to display /// public static readonly StyledProperty DeviceProperty = - AvaloniaProperty.Register(nameof(Device), notifying: DeviceUpdated); - - private static void DeviceUpdated(IAvaloniaObject sender, bool before) - { - if (!before) - ((DeviceVisualizer) sender).SetupForDevice(); - } + AvaloniaProperty.Register(nameof(Device)); /// /// Gets or sets the to display @@ -209,6 +208,8 @@ public class DeviceVisualizer : Control public static readonly StyledProperty?> HighlightedLedsProperty = AvaloniaProperty.Register?>(nameof(HighlightedLeds)); + private bool _loading; + /// /// Gets or sets a list of LEDs to highlight /// @@ -274,6 +275,7 @@ public class DeviceVisualizer : Control return; _deviceBounds = MeasureDevice(); + _loading = true; Device.RgbDevice.PropertyChanged += DevicePropertyChanged; Device.DeviceUpdated += DeviceUpdated; @@ -289,22 +291,22 @@ public class DeviceVisualizer : Control ArtemisDevice? device = Device; Dispatcher.UIThread.Post(() => { - if (device.Layout?.Image == null || !File.Exists(device.Layout.Image.LocalPath)) - { - _deviceImage?.Dispose(); - _deviceImage = null; - return; - } - try { + if (device.Layout?.Image == null || !File.Exists(device.Layout.Image.LocalPath)) + { + _deviceImage?.Dispose(); + _deviceImage = null; + return; + } + // Create a bitmap that'll be used to render the device and LED images just once // Render 4 times the actual size of the device to make sure things look sharp when zoomed in RenderTargetBitmap renderTargetBitmap = new(new PixelSize((int) device.RgbDevice.ActualSize.Width * 2, (int) device.RgbDevice.ActualSize.Height * 2)); - using IDrawingContextImpl context = renderTargetBitmap.CreateDrawingContext(new ImmediateRenderer(this)); + using DrawingContext context = renderTargetBitmap.CreateDrawingContext(); using Bitmap bitmap = new(device.Layout.Image.LocalPath); - context.DrawBitmap(bitmap.PlatformImpl, 1, new Rect(bitmap.Size), new Rect(renderTargetBitmap.Size), BitmapInterpolationMode.HighQuality); + context.DrawImage(bitmap, new Rect(bitmap.Size), new Rect(renderTargetBitmap.Size), BitmapInterpolationMode.HighQuality); lock (_deviceVisualizerLeds) { @@ -315,12 +317,16 @@ public class DeviceVisualizer : Control _deviceImage?.Dispose(); _deviceImage = renderTargetBitmap; - Dispatcher.UIThread.Post(InvalidateMeasure); + InvalidateMeasure(); } catch (Exception) { // ignored } + finally + { + _loading = false; + } }); } diff --git a/src/Artemis.UI.Shared/Controls/DeviceVisualizerLed.cs b/src/Artemis.UI.Shared/Controls/DeviceVisualizerLed.cs index f1d762431..30bb72b76 100644 --- a/src/Artemis.UI.Shared/Controls/DeviceVisualizerLed.cs +++ b/src/Artemis.UI.Shared/Controls/DeviceVisualizerLed.cs @@ -4,8 +4,6 @@ using Artemis.Core; using Avalonia; using Avalonia.Media; using Avalonia.Media.Imaging; -using Avalonia.Platform; -using Avalonia.Visuals.Media.Imaging; using RGB.NET.Core; using Color = Avalonia.Media.Color; using Point = Avalonia.Point; @@ -40,7 +38,7 @@ internal class DeviceVisualizerLed public Rect LedRect { get; set; } public Geometry? DisplayGeometry { get; private set; } - public void DrawBitmap(IDrawingContextImpl drawingContext, double scale) + public void DrawBitmap(DrawingContext drawingContext, double scale) { if (Led.Layout?.Image == null || !File.Exists(Led.Layout.Image.LocalPath)) return; @@ -48,9 +46,8 @@ internal class DeviceVisualizerLed try { using Bitmap bitmap = new(Led.Layout.Image.LocalPath); - drawingContext.DrawBitmap( - bitmap.PlatformImpl, - 1, + drawingContext.DrawImage( + bitmap, new Rect(bitmap.Size), new Rect(Led.RgbLed.Location.X * scale, Led.RgbLed.Location.Y * scale, Led.RgbLed.Size.Width * scale, Led.RgbLed.Size.Height * scale), BitmapInterpolationMode.HighQuality diff --git a/src/Artemis.UI.Shared/Controls/DraggableNumberBox.axaml b/src/Artemis.UI.Shared/Controls/DraggableNumberBox.axaml index d480b0c51..3edd26150 100644 --- a/src/Artemis.UI.Shared/Controls/DraggableNumberBox.axaml +++ b/src/Artemis.UI.Shared/Controls/DraggableNumberBox.axaml @@ -23,7 +23,7 @@ - /// Represents a number box that can be mutated by dragging over it horizontally /// -public class DraggableNumberBox : UserControl +public partial class DraggableNumberBox : UserControl { /// /// Defines the property. /// - public static readonly StyledProperty ValueProperty = AvaloniaProperty.Register(nameof(Value), defaultBindingMode: BindingMode.TwoWay, notifying: ValueChanged); + public static readonly StyledProperty ValueProperty = AvaloniaProperty.Register(nameof(Value), defaultBindingMode: BindingMode.TwoWay); /// /// Defines the property. @@ -56,7 +56,6 @@ public class DraggableNumberBox : UserControl /// public static readonly StyledProperty SuffixProperty = AvaloniaProperty.Register(nameof(Suffix)); - private readonly NumberBox _numberBox; private TextBox? _inputTextBox; private double _lastX; private bool _moved; @@ -69,13 +68,13 @@ public class DraggableNumberBox : UserControl public DraggableNumberBox() { InitializeComponent(); - _numberBox = this.Get("NumberBox"); - _numberBox.Value = Value; + InnerNumberBox.Value = Value; PointerPressed += OnPointerPressed; PointerMoved += OnPointerMoved; PointerReleased += OnPointerReleased; - + PropertyChanged += OnPropertyChanged; + AddHandler(KeyUpEvent, HandleKeyUp, RoutingStrategies.Direct | RoutingStrategies.Tunnel | RoutingStrategies.Bubble, true); } @@ -160,36 +159,27 @@ public class DraggableNumberBox : UserControl /// Occurs when the user finishes dragging over the control. /// public event TypedEventHandler? DragFinished; - - private static void ValueChanged(IAvaloniaObject sender, bool before) + + private void SetNumberBoxValue(double value) { - if (before) + if (!(Math.Abs(InnerNumberBox.Value - Value) > 0.00001)) return; - DraggableNumberBox draggable = (DraggableNumberBox) sender; - if (!(Math.Abs(draggable._numberBox.Value - draggable.Value) > 0.00001)) - return; - - draggable._updating = true; - draggable._numberBox.Value = draggable.Value; - draggable._updating = false; + _updating = true; + InnerNumberBox.Value = Value; + _updating = false; } private void HandleKeyUp(object? sender, KeyEventArgs e) { if (e.Key == Key.Enter || e.Key == Key.Escape) - Parent?.Focus(); - } - - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); + FocusManager.Instance?.Focus(Parent as IInputElement); } private void OnPointerPressed(object? sender, PointerPressedEventArgs e) { PointerPoint point = e.GetCurrentPoint(this); - _inputTextBox = _numberBox.FindDescendantOfType(); + _inputTextBox = InnerNumberBox.FindDescendantOfType(); _moved = false; _startX = point.Position.X; _lastX = point.Position.X; @@ -211,7 +201,7 @@ public class DraggableNumberBox : UserControl if (!_moved) { // Let our parent take focus, it would make more sense to take focus ourselves but that hides the collider - Parent?.Focus(); + FocusManager.Instance?.Focus(Parent as IInputElement); _moved = true; e.Pointer.Capture(this); DragStarted?.Invoke(this, EventArgs.Empty); @@ -253,6 +243,12 @@ public class DraggableNumberBox : UserControl e.Handled = true; } + + private void OnPropertyChanged(object? sender, AvaloniaPropertyChangedEventArgs e) + { + if (e.Property == ValueProperty) + SetNumberBoxValue(Value); + } private void NumberBox_OnValueChanged(NumberBox sender, NumberBoxValueChangedEventArgs args) { @@ -261,17 +257,17 @@ public class DraggableNumberBox : UserControl if (args.NewValue < Minimum) { - _numberBox.Value = Minimum; + InnerNumberBox.Value = Minimum; return; } if (args.NewValue > Maximum) { - _numberBox.Value = Maximum; + InnerNumberBox.Value = Maximum; return; } - if (Math.Abs(Value - _numberBox.Value) > 0.00001) - Value = _numberBox.Value; + if (Math.Abs(Value - InnerNumberBox.Value) > 0.00001) + Value = InnerNumberBox.Value; } } \ No newline at end of file diff --git a/src/Artemis.UI.Shared/Controls/EnumComboBox.axaml b/src/Artemis.UI.Shared/Controls/EnumComboBox.axaml index 59195d73a..1849c97e5 100644 --- a/src/Artemis.UI.Shared/Controls/EnumComboBox.axaml +++ b/src/Artemis.UI.Shared/Controls/EnumComboBox.axaml @@ -4,7 +4,7 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" x:Class="Artemis.UI.Shared.EnumComboBox"> - + diff --git a/src/Artemis.UI.Shared/Controls/EnumComboBox.axaml.cs b/src/Artemis.UI.Shared/Controls/EnumComboBox.axaml.cs index f264b595e..ff2869519 100644 --- a/src/Artemis.UI.Shared/Controls/EnumComboBox.axaml.cs +++ b/src/Artemis.UI.Shared/Controls/EnumComboBox.axaml.cs @@ -13,13 +13,12 @@ namespace Artemis.UI.Shared; /// /// Represents a combobox that can display the values of an enum. /// -public class EnumComboBox : UserControl +public partial class EnumComboBox : UserControl { /// /// Gets or sets the currently selected value /// - public static readonly StyledProperty ValueProperty = - AvaloniaProperty.Register(nameof(Value), defaultBindingMode: BindingMode.TwoWay, notifying: ValueChanged); + public static readonly StyledProperty ValueProperty = AvaloniaProperty.Register(nameof(Value), defaultBindingMode: BindingMode.TwoWay); private readonly ObservableCollection<(Enum, string)> _currentValues = new(); private Type? _currentType; @@ -31,9 +30,19 @@ public class EnumComboBox : UserControl /// public EnumComboBox() { + PropertyChanged += OnPropertyChanged; InitializeComponent(); } + private void OnPropertyChanged(object? sender, AvaloniaPropertyChangedEventArgs e) + { + if (e.Property == ValueProperty) + { + UpdateValues(); + UpdateSelection(); + } + } + /// /// Gets or sets the currently selected value /// @@ -43,20 +52,6 @@ public class EnumComboBox : UserControl set => SetValue(ValueProperty, value); } - private static void ValueChanged(IAvaloniaObject sender, bool before) - { - if (sender is EnumComboBox enumCombo && !before) - { - enumCombo.UpdateValues(); - enumCombo.UpdateSelection(); - } - } - - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } - private void OnSelectionChanged(object? sender, SelectionChangedEventArgs e) { if (_enumComboBox == null || _enumComboBox.SelectedIndex == -1) @@ -95,7 +90,7 @@ public class EnumComboBox : UserControl /// protected override void OnAttachedToLogicalTree(LogicalTreeAttachmentEventArgs e) { - _enumComboBox = this.Get("EnumComboBox"); + _enumComboBox = this.Get("ChildEnumComboBox"); _enumComboBox.Items = _currentValues; UpdateValues(); diff --git a/src/Artemis.UI.Shared/Controls/GradientPicker/GradientPicker.cs b/src/Artemis.UI.Shared/Controls/GradientPicker/GradientPicker.cs index 5bc9eebd5..11215c7f0 100644 --- a/src/Artemis.UI.Shared/Controls/GradientPicker/GradientPicker.cs +++ b/src/Artemis.UI.Shared/Controls/GradientPicker/GradientPicker.cs @@ -27,7 +27,7 @@ public class GradientPicker : TemplatedControl /// Gets or sets the color gradient. /// public static readonly StyledProperty ColorGradientProperty = - AvaloniaProperty.Register(nameof(ColorGradient), notifying: ColorGradientChanged, defaultValue: ColorGradient.GetUnicornBarf()); + AvaloniaProperty.Register(nameof(ColorGradient), defaultValue: ColorGradient.GetUnicornBarf()); /// /// Gets or sets the currently selected color stop. @@ -45,7 +45,7 @@ public class GradientPicker : TemplatedControl /// Gets or sets a storage provider to use for storing and loading gradients. /// public static readonly StyledProperty StorageProviderProperty = - AvaloniaProperty.Register(nameof(StorageProvider), notifying: StorageProviderChanged); + AvaloniaProperty.Register(nameof(StorageProvider)); /// /// Gets the linear gradient brush representing the color gradient. @@ -66,7 +66,7 @@ public class GradientPicker : TemplatedControl AvaloniaProperty.RegisterDirect(nameof(EditingColorGradient), g => g.EditingColorGradient); private readonly ICommand _deleteStop; - private ColorPicker? _colorPicker; + private FAColorPicker? _colorPicker; private Button? _flipStops; private Border? _gradient; private Button? _randomize; @@ -94,6 +94,8 @@ public class GradientPicker : TemplatedControl SelectedColorStop = EditingColorGradient.ElementAtOrDefault(index); }); + + PropertyChanged += OnPropertyChanged; } /// @@ -176,7 +178,7 @@ public class GradientPicker : TemplatedControl if (_randomize != null) _randomize.Click -= RandomizeOnClick; - _colorPicker = e.NameScope.Find("ColorPicker"); + _colorPicker = e.NameScope.Find("ColorPicker"); _gradient = e.NameScope.Find("Gradient"); _spreadStops = e.NameScope.Find public static readonly StyledProperty ColorGradientProperty = - AvaloniaProperty.Register(nameof(ColorGradient), notifying: ColorGradientChanged); + AvaloniaProperty.Register(nameof(ColorGradient)); /// /// Gets or sets a boolean indicating whether the gradient picker should be in compact mode or not. @@ -48,6 +47,12 @@ public class GradientPickerButton : TemplatedControl private Button? _button; private ColorGradient? _lastColorGradient; + /// + public GradientPickerButton() + { + PropertyChanged += OnPropertyChanged; + } + /// /// Gets or sets the color gradient. /// @@ -105,12 +110,6 @@ public class GradientPickerButton : TemplatedControl #endregion - private static void ColorGradientChanged(IAvaloniaObject sender, bool before) - { - if (!before) - (sender as GradientPickerButton)?.Subscribe(); - } - private void Subscribe() { Unsubscribe(); @@ -178,6 +177,12 @@ public class GradientPickerButton : TemplatedControl LinearGradientBrush.GradientStops = collection; } + private void OnPropertyChanged(object? sender, AvaloniaPropertyChangedEventArgs e) + { + if (e.Property == ColorGradientProperty) + Subscribe(); + } + #region Overrides of Visual /// diff --git a/src/Artemis.UI.Shared/Controls/GradientPicker/GradientPickerColorStop.cs b/src/Artemis.UI.Shared/Controls/GradientPicker/GradientPickerColorStop.cs index 4e4502288..4bb8aa8e2 100644 --- a/src/Artemis.UI.Shared/Controls/GradientPicker/GradientPickerColorStop.cs +++ b/src/Artemis.UI.Shared/Controls/GradientPicker/GradientPickerColorStop.cs @@ -16,7 +16,7 @@ internal class GradientPickerColorStop : TemplatedControl /// Gets or sets the gradient picker. /// public static readonly StyledProperty GradientPickerProperty = - AvaloniaProperty.Register(nameof(GradientPicker), notifying: Notifying); + AvaloniaProperty.Register(nameof(GradientPicker)); /// /// Gets or sets the color stop. @@ -28,8 +28,8 @@ internal class GradientPickerColorStop : TemplatedControl /// Gets or sets the position reference to use when positioning and dragging this color stop. /// If then dragging is not enabled. /// - public static readonly StyledProperty PositionReferenceProperty = - AvaloniaProperty.Register(nameof(PositionReference)); + public static readonly StyledProperty PositionReferenceProperty = + AvaloniaProperty.Register(nameof(PositionReference)); /// /// Gets the linear gradient brush representing the color gradient. @@ -47,7 +47,16 @@ internal class GradientPickerColorStop : TemplatedControl public GradientPicker? GradientPicker { get => GetValue(GradientPickerProperty); - set => SetValue(GradientPickerProperty, value); + set + { + if (GradientPicker != null) + GradientPicker.PropertyChanged -= GradientPickerOnPropertyChanged; + SetValue(GradientPickerProperty, value); + if (GradientPicker != null) + GradientPicker.PropertyChanged += GradientPickerOnPropertyChanged; + + IsSelected = ReferenceEquals(GradientPicker?.SelectedColorStop, ColorStop); + } } /// @@ -63,7 +72,7 @@ internal class GradientPickerColorStop : TemplatedControl /// Gets or sets the position reference to use when positioning and dragging this color stop. /// If then dragging is not enabled. /// - public IControl? PositionReference + public Control? PositionReference { get => GetValue(PositionReferenceProperty); set => SetValue(PositionReferenceProperty, value); @@ -85,19 +94,6 @@ internal class GradientPickerColorStop : TemplatedControl } } - private static void Notifying(IAvaloniaObject sender, bool before) - { - if (sender is not GradientPickerColorStop self) - return; - - if (before && self.GradientPicker != null) - self.GradientPicker.PropertyChanged -= self.GradientPickerOnPropertyChanged; - else if (self.GradientPicker != null) - self.GradientPicker.PropertyChanged += self.GradientPickerOnPropertyChanged; - - self.IsSelected = ReferenceEquals(self.GradientPicker?.SelectedColorStop, self.ColorStop); - } - private void GradientPickerOnPropertyChanged(object? sender, AvaloniaPropertyChangedEventArgs e) { if (GradientPicker != null && e.Property == GradientPicker.SelectedColorStopProperty) diff --git a/src/Artemis.UI.Shared/Controls/HotkeyBox.axaml b/src/Artemis.UI.Shared/Controls/HotkeyBox.axaml index 0e53282e1..6b7e0c0c1 100644 --- a/src/Artemis.UI.Shared/Controls/HotkeyBox.axaml +++ b/src/Artemis.UI.Shared/Controls/HotkeyBox.axaml @@ -10,8 +10,16 @@ diff --git a/src/Artemis.UI.Shared/Controls/HotkeyBox.axaml.cs b/src/Artemis.UI.Shared/Controls/HotkeyBox.axaml.cs index 0c50e69e4..555d21320 100644 --- a/src/Artemis.UI.Shared/Controls/HotkeyBox.axaml.cs +++ b/src/Artemis.UI.Shared/Controls/HotkeyBox.axaml.cs @@ -8,6 +8,8 @@ using Avalonia.Data; using Avalonia.Input; using Avalonia.Interactivity; using Avalonia.Markup.Xaml; +using Avalonia.Threading; +using DryIoc; using FluentAvalonia.Core; using Humanizer; using Material.Icons; @@ -17,48 +19,64 @@ namespace Artemis.UI.Shared; /// /// Represents a control that can be used to display or edit instances. /// -public class HotkeyBox : UserControl +public partial class HotkeyBox : UserControl { - private readonly TextBox _displayTextBox; + private readonly IInputService _inputService; /// /// Creates a new instance of the class /// public HotkeyBox() { - InitializeComponent(); + _inputService = UI.Locator.Resolve(); - _displayTextBox = this.Find("DisplayTextBox"); - _displayTextBox.KeyDown += DisplayTextBoxOnKeyDown; - _displayTextBox.KeyUp += DisplayTextBoxOnKeyUp; + InitializeComponent(); + PropertyChanged += OnPropertyChanged; UpdateDisplayTextBox(); } - private static void HotkeyChanging(IAvaloniaObject sender, bool before) + protected override void OnGotFocus(GotFocusEventArgs e) { - ((HotkeyBox) sender).UpdateDisplayTextBox(); + _inputService.KeyboardKeyDown += InputServiceOnKeyboardKeyDown; + _inputService.KeyboardKeyUp += InputServiceOnKeyboardKeyUp; + + base.OnGotFocus(e); } - private void DisplayTextBoxOnKeyDown(object? sender, KeyEventArgs e) + protected override void OnLostFocus(RoutedEventArgs e) { - if (e.Key >= Key.LeftShift && e.Key <= Key.RightAlt) + _inputService.KeyboardKeyDown -= InputServiceOnKeyboardKeyDown; + _inputService.KeyboardKeyUp -= InputServiceOnKeyboardKeyUp; + + base.OnLostFocus(e); + } + + private void OnPropertyChanged(object? sender, AvaloniaPropertyChangedEventArgs e) + { + if (e.Property == HotkeyProperty) + UpdateDisplayTextBox(); + } + + private void InputServiceOnKeyboardKeyDown(object? sender, ArtemisKeyboardKeyEventArgs e) + { + if (e.Key >= KeyboardKey.LeftShift && e.Key <= KeyboardKey.RightAlt) return; Hotkey ??= new Hotkey(); - Hotkey.Key = (KeyboardKey?) e.Key; - Hotkey.Modifiers = (KeyboardModifierKey?) e.KeyModifiers; - UpdateDisplayTextBox(); - HotkeyChanged?.Invoke(this, EventArgs.Empty); + Hotkey.Key = e.Key; + Hotkey.Modifiers = e.Modifiers; - e.Handled = true; + Dispatcher.UIThread.Post(() => + { + UpdateDisplayTextBox(); + HotkeyChanged?.Invoke(this, EventArgs.Empty); + }); } - private void DisplayTextBoxOnKeyUp(object? sender, KeyEventArgs e) + private void InputServiceOnKeyboardKeyUp(object? sender, ArtemisKeyboardKeyEventArgs e) { - if (e.KeyModifiers == KeyModifiers.None) - FocusManager.Instance?.Focus(null); - - e.Handled = true; + if (e.Modifiers == KeyboardModifierKey.None) + Dispatcher.UIThread.Post(() => FocusManager.Instance?.Focus(null)); } private void UpdateDisplayTextBox() @@ -69,13 +87,8 @@ public class HotkeyBox : UserControl if (Hotkey?.Key != null) display = string.IsNullOrEmpty(display) ? Hotkey.Key.ToString() : $"{display}+{Hotkey.Key}"; - _displayTextBox.Text = display; - _displayTextBox.CaretIndex = _displayTextBox.Text?.Length ?? 0; - } - - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); + DisplayTextBox.Text = display; + DisplayTextBox.CaretIndex = DisplayTextBox.Text?.Length ?? 0; } private void Button_OnClick(object? sender, RoutedEventArgs e) @@ -92,20 +105,17 @@ public class HotkeyBox : UserControl /// Gets or sets the currently displayed icon as either a or an /// pointing to an SVG /// - public static readonly StyledProperty HotkeyProperty = - AvaloniaProperty.Register(nameof(Hotkey), defaultBindingMode: BindingMode.TwoWay, notifying: HotkeyChanging); + public static readonly StyledProperty HotkeyProperty = AvaloniaProperty.Register(nameof(Hotkey), defaultBindingMode: BindingMode.TwoWay); /// /// Gets or sets the watermark of the hotkey box when it is empty. /// - public static readonly StyledProperty WatermarkProperty = - AvaloniaProperty.Register(nameof(Watermark)); + public static readonly StyledProperty WatermarkProperty = AvaloniaProperty.Register(nameof(Watermark)); /// /// Gets or sets a boolean indicating whether the watermark should float above the hotkey box when it is not empty. /// - public static readonly StyledProperty UseFloatingWatermarkProperty = - AvaloniaProperty.Register(nameof(UseFloatingWatermark)); + public static readonly StyledProperty UseFloatingWatermarkProperty = AvaloniaProperty.Register(nameof(UseFloatingWatermark)); /// /// Gets or sets the currently displayed icon as either a or an diff --git a/src/Artemis.UI.Shared/Controls/ProfileConfigurationIcon.axaml.cs b/src/Artemis.UI.Shared/Controls/ProfileConfigurationIcon.axaml.cs index c119f0ab2..4dd0711ba 100644 --- a/src/Artemis.UI.Shared/Controls/ProfileConfigurationIcon.axaml.cs +++ b/src/Artemis.UI.Shared/Controls/ProfileConfigurationIcon.axaml.cs @@ -3,13 +3,13 @@ using System.IO; using Artemis.Core; using Avalonia; using Avalonia.Controls; +using Avalonia.Controls.Documents; using Avalonia.Layout; using Avalonia.LogicalTree; using Avalonia.Markup.Xaml; using Avalonia.Media; using Avalonia.Media.Imaging; using Avalonia.Threading; -using Avalonia.Visuals.Media.Imaging; using Material.Icons; using Material.Icons.Avalonia; @@ -18,7 +18,7 @@ namespace Artemis.UI.Shared; /// /// Represents a control that can display the icon of a specific . /// -public class ProfileConfigurationIcon : UserControl, IDisposable +public partial class ProfileConfigurationIcon : UserControl, IDisposable { private Stream? _stream; @@ -72,18 +72,13 @@ public class ProfileConfigurationIcon : UserControl, IDisposable Content = new Border { - Background = TextBlock.GetForeground(this), + Background = TextElement.GetForeground(this), VerticalAlignment = VerticalAlignment.Stretch, HorizontalAlignment = HorizontalAlignment.Stretch, OpacityMask = new ImageBrush(new Bitmap(stream)) {BitmapInterpolationMode = BitmapInterpolationMode.MediumQuality} }; } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } - private void OnDetachedFromLogicalTree(object? sender, LogicalTreeAttachmentEventArgs e) { if (ConfigurationIcon != null) diff --git a/src/Artemis.UI.Shared/Controls/SelectionRectangle.cs b/src/Artemis.UI.Shared/Controls/SelectionRectangle.cs index d869a5730..8e997d532 100644 --- a/src/Artemis.UI.Shared/Controls/SelectionRectangle.cs +++ b/src/Artemis.UI.Shared/Controls/SelectionRectangle.cs @@ -40,8 +40,8 @@ public class SelectionRectangle : Control /// /// Defines the property. /// - public static readonly StyledProperty InputElementProperty = - AvaloniaProperty.Register(nameof(InputElement), notifying: OnInputElementChanged); + public static readonly StyledProperty InputElementProperty = + AvaloniaProperty.Register(nameof(InputElement)); /// /// Defines the property. @@ -61,7 +61,7 @@ public class SelectionRectangle : Control private Rect? _displayRect; private bool _isSelecting; private Point _lastPosition; - private IControl? _oldInputElement; + private InputElement? _oldInputElement; private Point _startPosition; /// @@ -69,6 +69,14 @@ public class SelectionRectangle : Control { AffectsRender(BackgroundProperty, BorderBrushProperty, BorderThicknessProperty); IsHitTestVisible = false; + + PropertyChanged += OnPropertyChanged; + } + + private void OnPropertyChanged(object? sender, AvaloniaPropertyChangedEventArgs e) + { + if (e.Property == InputElementProperty) + SubscribeToInputElement(); } /// @@ -110,7 +118,7 @@ public class SelectionRectangle : Control /// /// Gets or sets the element that captures input for the selection rectangle. /// - public IControl? InputElement + public InputElement? InputElement { get => GetValue(InputElementProperty); set => SetValue(InputElementProperty, value); @@ -162,11 +170,6 @@ public class SelectionRectangle : Control SelectionFinished?.Invoke(this, e); } - private static void OnInputElementChanged(IAvaloniaObject sender, bool before) - { - ((SelectionRectangle) sender).SubscribeToInputElement(); - } - private void ParentOnPointerMoved(object? sender, PointerEventArgs e) { // Point moved seems to trigger when the element under the mouse changes? @@ -185,13 +188,13 @@ public class SelectionRectangle : Control { e.Pointer.Capture(this); - _startPosition = e.GetPosition(Parent); - _absoluteStartPosition = e.GetPosition(VisualRoot); + _startPosition = e.GetPosition(Parent as Visual); + _absoluteStartPosition = e.GetPosition(VisualRoot as Visual); _displayRect = null; } - Point currentPosition = e.GetPosition(Parent); - Point absoluteCurrentPosition = e.GetPosition(VisualRoot); + Point currentPosition = e.GetPosition(Parent as Visual); + Point absoluteCurrentPosition = e.GetPosition(VisualRoot as Visual); _displayRect = new Rect( new Point(Math.Min(_startPosition.X, currentPosition.X), Math.Min(_startPosition.Y, currentPosition.Y)), diff --git a/src/Artemis.UI.Shared/Converters/ParentWidthPercentageConverter.cs b/src/Artemis.UI.Shared/Converters/ParentWidthPercentageConverter.cs index 2d8219d0e..4af9f7c86 100644 --- a/src/Artemis.UI.Shared/Converters/ParentWidthPercentageConverter.cs +++ b/src/Artemis.UI.Shared/Converters/ParentWidthPercentageConverter.cs @@ -15,7 +15,7 @@ public class ParentWidthPercentageConverter : IValueConverter /// public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture) { - if (parameter is not IControl parent || value is not double percentage) + if (parameter is not Control parent || value is not double percentage) return value; return parent.Width / 100.0 * percentage; @@ -24,7 +24,7 @@ public class ParentWidthPercentageConverter : IValueConverter /// public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) { - if (parameter is not IControl parent || value is not double real) + if (parameter is not Control parent || value is not double real) return value; return real / parent.Width * 100.0; diff --git a/src/Artemis.UI.Shared/DefaultTypes/DataModel/Display/DefaultDataModelDisplayView.axaml.cs b/src/Artemis.UI.Shared/DefaultTypes/DataModel/Display/DefaultDataModelDisplayView.axaml.cs index 74bffd403..2980cf877 100644 --- a/src/Artemis.UI.Shared/DefaultTypes/DataModel/Display/DefaultDataModelDisplayView.axaml.cs +++ b/src/Artemis.UI.Shared/DefaultTypes/DataModel/Display/DefaultDataModelDisplayView.axaml.cs @@ -6,7 +6,7 @@ namespace Artemis.UI.Shared.DefaultTypes.DataModel.Display; /// /// Represents a default data model display view. /// -public class DefaultDataModelDisplayView : UserControl +public partial class DefaultDataModelDisplayView : UserControl { /// /// Creates a new instance of the class. @@ -15,9 +15,4 @@ public class DefaultDataModelDisplayView : UserControl { InitializeComponent(); } - - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } } \ No newline at end of file diff --git a/src/Artemis.UI.Shared/DefaultTypes/DataModel/Display/SKColorDataModelDisplayView.axaml.cs b/src/Artemis.UI.Shared/DefaultTypes/DataModel/Display/SKColorDataModelDisplayView.axaml.cs index 548987c18..57a8c867a 100644 --- a/src/Artemis.UI.Shared/DefaultTypes/DataModel/Display/SKColorDataModelDisplayView.axaml.cs +++ b/src/Artemis.UI.Shared/DefaultTypes/DataModel/Display/SKColorDataModelDisplayView.axaml.cs @@ -7,7 +7,7 @@ namespace Artemis.UI.Shared.DefaultTypes.DataModel.Display; /// /// Represents a data model display view used to display values. /// -public class SKColorDataModelDisplayView : UserControl +public partial class SKColorDataModelDisplayView : UserControl { /// /// Creates a new instance of the class. @@ -17,8 +17,4 @@ public class SKColorDataModelDisplayView : UserControl InitializeComponent(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } } \ No newline at end of file diff --git a/src/Artemis.UI.Shared/DryIoc/ContainerExtensions.cs b/src/Artemis.UI.Shared/DryIoc/ContainerExtensions.cs index 4c4711b02..1c86ecf84 100644 --- a/src/Artemis.UI.Shared/DryIoc/ContainerExtensions.cs +++ b/src/Artemis.UI.Shared/DryIoc/ContainerExtensions.cs @@ -17,5 +17,7 @@ public static class ContainerExtensions { Assembly artemisShared = typeof(IArtemisSharedUIService).GetAssembly(); container.RegisterMany(new[] { artemisShared }, type => type.IsAssignableTo(), Reuse.Singleton); + + UI.Locator = container; } } \ No newline at end of file diff --git a/src/Artemis.UI.Shared/Extensions/VisualExtensions.cs b/src/Artemis.UI.Shared/Extensions/VisualExtensions.cs index d01649eb0..45e97e130 100644 --- a/src/Artemis.UI.Shared/Extensions/VisualExtensions.cs +++ b/src/Artemis.UI.Shared/Extensions/VisualExtensions.cs @@ -6,7 +6,7 @@ using Avalonia.VisualTree; namespace Artemis.UI.Shared.Extensions; /// -/// Provides extension methods for Avalonia's type +/// Provides extension methods for Avalonia's type /// public static class VisualExtensions { @@ -16,15 +16,15 @@ public static class VisualExtensions /// The type the children should have. /// The root visual at which to start searching. /// A recursive list of all visual children of type . - public static List GetVisualChildrenOfType(this IVisual root) + public static List GetVisualChildrenOfType(this Visual root) { List result = new(); - List? visualChildren = root.GetVisualChildren()?.ToList(); + List? visualChildren = root.GetVisualChildren()?.ToList(); if (visualChildren == null || !visualChildren.Any()) return result; - foreach (IVisual visualChild in visualChildren) + foreach (Visual visualChild in visualChildren) { if (visualChild is T toFind) result.Add(toFind); @@ -41,15 +41,15 @@ public static class VisualExtensions /// The type of data context the children should have. /// The root visual at which to start searching. /// A recursive list of all visual children with a data context of type . - public static List GetVisualChildrenOfDataContextType(this IVisual root) + public static List GetVisualChildrenOfDataContextType(this Visual root) { List result = new(); - List? visualChildren = root.GetVisualChildren()?.ToList(); + List? visualChildren = root.GetVisualChildren()?.ToList(); if (visualChildren == null || !visualChildren.Any()) return result; - foreach (IVisual visualChild in visualChildren) + foreach (Visual visualChild in visualChildren) { if (visualChild is IDataContextProvider dataContextProvider && dataContextProvider.DataContext is T toFind) result.Add(toFind); diff --git a/src/Artemis.UI.Shared/ReactiveCoreWindow.cs b/src/Artemis.UI.Shared/ReactiveAppWindow.cs similarity index 56% rename from src/Artemis.UI.Shared/ReactiveCoreWindow.cs rename to src/Artemis.UI.Shared/ReactiveAppWindow.cs index 295f4e6bb..58f4ad820 100644 --- a/src/Artemis.UI.Shared/ReactiveCoreWindow.cs +++ b/src/Artemis.UI.Shared/ReactiveAppWindow.cs @@ -4,8 +4,9 @@ using Avalonia; using Avalonia.Controls; using Avalonia.Media; using Avalonia.Media.Immutable; -using FluentAvalonia.UI.Controls; +using Avalonia.Styling; using FluentAvalonia.UI.Media; +using FluentAvalonia.UI.Windowing; using ReactiveUI; namespace Artemis.UI.Shared; @@ -17,18 +18,18 @@ namespace Artemis.UI.Shared; /// and vice versa. /// /// ViewModel type. -public class ReactiveCoreWindow : CoreWindow, IViewFor where TViewModel : class +public class ReactiveAppWindow : AppWindow, IViewFor where TViewModel : class { /// /// The ViewModel. /// public static readonly StyledProperty ViewModelProperty = AvaloniaProperty - .Register, TViewModel?>(nameof(ViewModel)); + .Register, TViewModel?>(nameof(ViewModel)); /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// - public ReactiveCoreWindow() + public ReactiveAppWindow() { // This WhenActivated block calls ViewModel's WhenActivated // block if the ViewModel implements IActivatableViewModel. @@ -46,13 +47,9 @@ public class ReactiveCoreWindow : CoreWindow, IViewFor w if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows) || !IsWindows11) return; - // Enable Mica on Windows 11, based on the FluentAvalonia sample application TransparencyBackgroundFallback = Brushes.Transparent; TransparencyLevelHint = WindowTransparencyLevel.Mica; - - Color2 color = this.TryFindResource("SolidBackgroundFillColorBase", out object? value) ? (Color) value! : new Color2(32, 32, 32); - color = color.LightenPercent(-0.5f); - Background = new ImmutableSolidColorBrush(color, 0.82); + TryEnableMicaEffect(); } private void OnDataContextChanged(object? value) @@ -70,6 +67,31 @@ public class ReactiveCoreWindow : CoreWindow, IViewFor w else if (DataContext != value) DataContext = value; } + private void TryEnableMicaEffect() + { + // The background colors for the Mica brush are still based around SolidBackgroundFillColorBase resource + // BUT since we can't control the actual Mica brush color, we have to use the window background to create + // the same effect. However, we can't use SolidBackgroundFillColorBase directly since its opaque, and if + // we set the opacity the color become lighter than we want. So we take the normal color, darken it and + // apply the opacity until we get the roughly the correct color + // NOTE that the effect still doesn't look right, but it suffices. Ideally we need access to the Mica + // CompositionBrush to properly change the color but I don't know if we can do that or not + if (ActualThemeVariant == ThemeVariant.Dark) + { + Color2 color = this.TryFindResource("SolidBackgroundFillColorBase", ThemeVariant.Dark, out object? value) ? (Color) value : new Color2(32, 32, 32); + color = color.LightenPercent(-0.5f); + + Background = new ImmutableSolidColorBrush(color, 0.78); + } + else if (ActualThemeVariant == ThemeVariant.Light) + { + // Similar effect here + Color2 color = this.TryFindResource("SolidBackgroundFillColorBase", ThemeVariant.Light, out object? value) ? (Color) value : new Color2(243, 243, 243); + color = color.LightenPercent(0.5f); + + Background = new ImmutableSolidColorBrush(color, 0.9); + } + } /// /// The ViewModel. diff --git a/src/Artemis.UI.Shared/Services/Builders/ContentDialogBuilder.cs b/src/Artemis.UI.Shared/Services/Builders/ContentDialogBuilder.cs index 275345b0e..92e681433 100644 --- a/src/Artemis.UI.Shared/Services/Builders/ContentDialogBuilder.cs +++ b/src/Artemis.UI.Shared/Services/Builders/ContentDialogBuilder.cs @@ -1,5 +1,4 @@ using System; -using System.Linq; using System.Threading.Tasks; using System.Windows.Input; using Avalonia.Controls; diff --git a/src/Artemis.UI.Shared/Services/Builders/FileDialogFilterBuilder.cs b/src/Artemis.UI.Shared/Services/Builders/FileDialogFilterBuilder.cs index a53d6dec5..e3c946804 100644 --- a/src/Artemis.UI.Shared/Services/Builders/FileDialogFilterBuilder.cs +++ b/src/Artemis.UI.Shared/Services/Builders/FileDialogFilterBuilder.cs @@ -1,4 +1,7 @@ -using Avalonia.Controls; +using System.Collections.Generic; +using System.Linq; +using Avalonia.Controls; +using Avalonia.Platform.Storage; namespace Artemis.UI.Shared.Services.Builders; @@ -7,11 +10,12 @@ namespace Artemis.UI.Shared.Services.Builders; /// public class FileDialogFilterBuilder { - private readonly FileDialogFilter _filter; + private string _name; + private readonly List _extensions = new(); internal FileDialogFilterBuilder() { - _filter = new FileDialogFilter(); + _name = "Unknown"; } /// @@ -19,7 +23,7 @@ public class FileDialogFilterBuilder /// public FileDialogFilterBuilder WithName(string name) { - _filter.Name = name; + _name = name; return this; } @@ -28,12 +32,16 @@ public class FileDialogFilterBuilder /// public FileDialogFilterBuilder WithExtension(string extension) { - _filter.Extensions.Add(extension); + if (!_extensions.Contains(extension)) + _extensions.Add(extension); return this; } - internal FileDialogFilter Build() + internal FilePickerFileType Build() { - return _filter; + return new FilePickerFileType(_name) + { + Patterns = _extensions.Select(e => "*." + e).ToList() + }; } } \ No newline at end of file diff --git a/src/Artemis.UI.Shared/Services/Builders/NotificationBuilder.cs b/src/Artemis.UI.Shared/Services/Builders/NotificationBuilder.cs index ccf3c741f..5ba268315 100644 --- a/src/Artemis.UI.Shared/Services/Builders/NotificationBuilder.cs +++ b/src/Artemis.UI.Shared/Services/Builders/NotificationBuilder.cs @@ -116,7 +116,7 @@ public class NotificationBuilder /// public Action Show() { - IPanel? panel = _parent.Find("NotificationContainer"); + Panel? panel = _parent.Find("NotificationContainer"); if (panel == null) throw new ArtemisSharedUIException("Can't display a notification on a window without a NotificationContainer."); @@ -202,7 +202,7 @@ public class NotificationButtonBuilder return this; } - internal IControl Build() + internal Control Build() { if (_action != null) return new Button {Content = _text, Command = ReactiveCommand.Create(() => _action()), Classes = new Classes("AppBarButton")}; diff --git a/src/Artemis.UI.Shared/Services/Builders/OpenFileDialogBuilder.cs b/src/Artemis.UI.Shared/Services/Builders/OpenFileDialogBuilder.cs index af53d1e72..e3785eea9 100644 --- a/src/Artemis.UI.Shared/Services/Builders/OpenFileDialogBuilder.cs +++ b/src/Artemis.UI.Shared/Services/Builders/OpenFileDialogBuilder.cs @@ -1,7 +1,9 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; using Avalonia.Controls; +using Avalonia.Platform.Storage; namespace Artemis.UI.Shared.Services.Builders; @@ -10,8 +12,9 @@ namespace Artemis.UI.Shared.Services.Builders; /// public class OpenFileDialogBuilder { - private readonly OpenFileDialog _openFileDialog; private readonly Window _parent; + private readonly FilePickerOpenOptions _options; + private List? _fileTypeFilters; /// /// Creates a new instance of the class. @@ -20,7 +23,7 @@ public class OpenFileDialogBuilder internal OpenFileDialogBuilder(Window parent) { _parent = parent; - _openFileDialog = new OpenFileDialog(); + _options = new FilePickerOpenOptions(); } /// @@ -28,7 +31,7 @@ public class OpenFileDialogBuilder /// public OpenFileDialogBuilder WithAllowMultiple() { - _openFileDialog.AllowMultiple = true; + _options.AllowMultiple = true; return this; } @@ -37,7 +40,7 @@ public class OpenFileDialogBuilder /// public OpenFileDialogBuilder WithTitle(string? title) { - _openFileDialog.Title = title; + _options.Title = title; return this; } @@ -46,16 +49,7 @@ public class OpenFileDialogBuilder /// public OpenFileDialogBuilder WithDirectory(string? directory) { - _openFileDialog.Directory = directory; - return this; - } - - /// - /// Set the initial file name of the dialog - /// - public OpenFileDialogBuilder WithInitialFileName(string? initialFileName) - { - _openFileDialog.InitialFileName = initialFileName; + _options.SuggestedStartLocation = directory != null ? _parent.StorageProvider.TryGetFolderFromPathAsync(directory).GetAwaiter().GetResult() : null; return this; } @@ -67,8 +61,9 @@ public class OpenFileDialogBuilder FileDialogFilterBuilder builder = new(); configure(builder); - _openFileDialog.Filters ??= new List(); - _openFileDialog.Filters.Add(builder.Build()); + _fileTypeFilters ??= new List(); + _fileTypeFilters.Add(builder.Build()); + _options.FileTypeFilter = _fileTypeFilters; return this; } @@ -82,6 +77,7 @@ public class OpenFileDialogBuilder /// public async Task ShowAsync() { - return await _openFileDialog.ShowAsync(_parent); + IReadOnlyList files = await _parent.StorageProvider.OpenFilePickerAsync(_options); + return files.Select(f => f.Path.AbsolutePath).ToArray(); } } \ No newline at end of file diff --git a/src/Artemis.UI.Shared/Services/Builders/OpenFolderDialogBuilder.cs b/src/Artemis.UI.Shared/Services/Builders/OpenFolderDialogBuilder.cs index 47846d170..25305b25c 100644 --- a/src/Artemis.UI.Shared/Services/Builders/OpenFolderDialogBuilder.cs +++ b/src/Artemis.UI.Shared/Services/Builders/OpenFolderDialogBuilder.cs @@ -1,5 +1,8 @@ -using System.Threading.Tasks; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; using Avalonia.Controls; +using Avalonia.Platform.Storage; namespace Artemis.UI.Shared.Services.Builders; @@ -8,8 +11,8 @@ namespace Artemis.UI.Shared.Services.Builders; /// public class OpenFolderDialogBuilder { - private readonly OpenFolderDialog _openFolderDialog; private readonly Window _parent; + private readonly FolderPickerOpenOptions _options; /// /// Creates a new instance of the class. @@ -18,16 +21,15 @@ public class OpenFolderDialogBuilder internal OpenFolderDialogBuilder(Window parent) { _parent = parent; - _openFolderDialog = new OpenFolderDialog(); + _options = new FolderPickerOpenOptions {AllowMultiple = false}; } - /// /// Set the title of the dialog /// public OpenFolderDialogBuilder WithTitle(string? title) { - _openFolderDialog.Title = title; + _options.Title = title; return this; } @@ -36,7 +38,7 @@ public class OpenFolderDialogBuilder /// public OpenFolderDialogBuilder WithDirectory(string? directory) { - _openFolderDialog.Directory = directory; + _options.SuggestedStartLocation = directory != null ? _parent.StorageProvider.TryGetFolderFromPathAsync(directory).GetAwaiter().GetResult() : null; return this; } @@ -49,6 +51,7 @@ public class OpenFolderDialogBuilder /// public async Task ShowAsync() { - return await _openFolderDialog.ShowAsync(_parent); + IReadOnlyList folder = await _parent.StorageProvider.OpenFolderPickerAsync(_options); + return folder.FirstOrDefault()?.Path.AbsolutePath; } } \ No newline at end of file diff --git a/src/Artemis.UI.Shared/Services/Builders/SaveFileDialogBuilder.cs b/src/Artemis.UI.Shared/Services/Builders/SaveFileDialogBuilder.cs index 7662f7228..a4bc95f18 100644 --- a/src/Artemis.UI.Shared/Services/Builders/SaveFileDialogBuilder.cs +++ b/src/Artemis.UI.Shared/Services/Builders/SaveFileDialogBuilder.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Threading.Tasks; using Avalonia.Controls; +using Avalonia.Platform.Storage; namespace Artemis.UI.Shared.Services.Builders; @@ -11,8 +12,9 @@ namespace Artemis.UI.Shared.Services.Builders; public class SaveFileDialogBuilder { private readonly Window _parent; - private readonly SaveFileDialog _saveFileDialog; - + private readonly FilePickerSaveOptions _options; + private List? _fileTypeFilters; + /// /// Creates a new instance of the class. /// @@ -20,7 +22,7 @@ public class SaveFileDialogBuilder internal SaveFileDialogBuilder(Window parent) { _parent = parent; - _saveFileDialog = new SaveFileDialog(); + _options = new FilePickerSaveOptions(); } /// @@ -28,7 +30,7 @@ public class SaveFileDialogBuilder /// public SaveFileDialogBuilder WithTitle(string? title) { - _saveFileDialog.Title = title; + _options.Title = title; return this; } @@ -37,7 +39,7 @@ public class SaveFileDialogBuilder /// public SaveFileDialogBuilder WithDirectory(string? directory) { - _saveFileDialog.Directory = directory; + _options.SuggestedStartLocation = directory != null ? _parent.StorageProvider.TryGetFolderFromPathAsync(directory).GetAwaiter().GetResult() : null; return this; } @@ -46,16 +48,7 @@ public class SaveFileDialogBuilder /// public SaveFileDialogBuilder WithInitialFileName(string? initialFileName) { - _saveFileDialog.InitialFileName = initialFileName; - return this; - } - - /// - /// Set the default extension of the dialog - /// - public SaveFileDialogBuilder WithDefaultExtension(string? defaultExtension) - { - _saveFileDialog.DefaultExtension = defaultExtension; + _options.SuggestedFileName = initialFileName; return this; } @@ -67,8 +60,9 @@ public class SaveFileDialogBuilder FileDialogFilterBuilder builder = new(); configure(builder); - _saveFileDialog.Filters ??= new List(); - _saveFileDialog.Filters.Add(builder.Build()); + _fileTypeFilters ??= new List(); + _fileTypeFilters.Add(builder.Build()); + _options.FileTypeChoices = _fileTypeFilters; return this; } @@ -82,6 +76,7 @@ public class SaveFileDialogBuilder /// public async Task ShowAsync() { - return await _saveFileDialog.ShowAsync(_parent); + IStorageFile? path = await _parent.StorageProvider.SaveFilePickerAsync(_options); + return path?.Path.AbsolutePath; } } \ No newline at end of file diff --git a/src/Artemis.UI.Shared/Services/Window/ExceptionDialogView.axaml.cs b/src/Artemis.UI.Shared/Services/Window/ExceptionDialogView.axaml.cs index a80786d99..9aca2bcf9 100644 --- a/src/Artemis.UI.Shared/Services/Window/ExceptionDialogView.axaml.cs +++ b/src/Artemis.UI.Shared/Services/Window/ExceptionDialogView.axaml.cs @@ -4,7 +4,7 @@ using Avalonia.ReactiveUI; namespace Artemis.UI.Shared.Services; -internal class ExceptionDialogView : ReactiveWindow +internal partial class ExceptionDialogView : ReactiveWindow { public ExceptionDialogView() { @@ -14,8 +14,4 @@ internal class ExceptionDialogView : ReactiveWindow #endif } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } } \ No newline at end of file diff --git a/src/Artemis.UI.Shared/Styles/Artemis.axaml b/src/Artemis.UI.Shared/Styles/Artemis.axaml index 7b838cdbf..9907a4b20 100644 --- a/src/Artemis.UI.Shared/Styles/Artemis.axaml +++ b/src/Artemis.UI.Shared/Styles/Artemis.axaml @@ -32,15 +32,4 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/src/Artemis.UI.Shared/Styles/Border.axaml b/src/Artemis.UI.Shared/Styles/Border.axaml index e82655006..afcd9dee8 100644 --- a/src/Artemis.UI.Shared/Styles/Border.axaml +++ b/src/Artemis.UI.Shared/Styles/Border.axaml @@ -8,7 +8,7 @@ I'm in a panel yo! - + I'm in a panel yo! @@ -27,14 +27,7 @@ - - - - + - - + \ No newline at end of file diff --git a/src/Artemis.UI.Shared/Styles/Condensed.axaml b/src/Artemis.UI.Shared/Styles/Condensed.axaml index 7b9f44d08..f1afaf384 100644 --- a/src/Artemis.UI.Shared/Styles/Condensed.axaml +++ b/src/Artemis.UI.Shared/Styles/Condensed.axaml @@ -102,7 +102,7 @@ - diff --git a/src/Artemis.UI.Shared/Styles/Controls/DataModelPickerButton.axaml b/src/Artemis.UI.Shared/Styles/Controls/DataModelPickerButton.axaml index cd5bc317e..3308fedc9 100644 --- a/src/Artemis.UI.Shared/Styles/Controls/DataModelPickerButton.axaml +++ b/src/Artemis.UI.Shared/Styles/Controls/DataModelPickerButton.axaml @@ -27,20 +27,20 @@ - + diff --git a/src/Artemis.UI.Shared/Styles/Controls/GradientPicker.axaml b/src/Artemis.UI.Shared/Styles/Controls/GradientPicker.axaml index 9909d32ac..680168261 100644 --- a/src/Artemis.UI.Shared/Styles/Controls/GradientPicker.axaml +++ b/src/Artemis.UI.Shared/Styles/Controls/GradientPicker.axaml @@ -168,14 +168,14 @@ BorderBrush="{DynamicResource ButtonBorderBrush}" BorderThickness="0 0 1 0" Padding="0 0 10 0"> - + diff --git a/src/Artemis.UI.Shared/Styles/Controls/GradientPickerButton.axaml b/src/Artemis.UI.Shared/Styles/Controls/GradientPickerButton.axaml index b3f3b6213..13f5ae0a5 100644 --- a/src/Artemis.UI.Shared/Styles/Controls/GradientPickerButton.axaml +++ b/src/Artemis.UI.Shared/Styles/Controls/GradientPickerButton.axaml @@ -1,15 +1,13 @@  - + - @@ -31,14 +29,14 @@ - + Padding="0 0 12 0" + CornerRadius="{TemplateBinding CornerRadius}" + HorizontalAlignment="Stretch" + VerticalAlignment="Stretch" + HorizontalContentAlignment="Stretch" + VerticalContentAlignment="Stretch"> - + diff --git a/src/Artemis.UI.Shared/Styles/TextBox.axaml b/src/Artemis.UI.Shared/Styles/TextBox.axaml index c6b950b6d..dd9039a05 100644 --- a/src/Artemis.UI.Shared/Styles/TextBox.axaml +++ b/src/Artemis.UI.Shared/Styles/TextBox.axaml @@ -35,22 +35,20 @@ - - + + - - - + + + + VerticalScrollBarVisibility="{TemplateBinding (ScrollViewer.VerticalScrollBarVisibility)}" + IsScrollChainingEnabled="{TemplateBinding (ScrollViewer.IsScrollChainingEnabled)}" + AllowAutoHide="{TemplateBinding (ScrollViewer.AllowAutoHide)}"> + VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/> + Text="{TemplateBinding Text, Mode=TwoWay}" + CaretIndex="{TemplateBinding CaretIndex}" + SelectionStart="{TemplateBinding SelectionStart}" + SelectionEnd="{TemplateBinding SelectionEnd}" + TextAlignment="{TemplateBinding TextAlignment}" + TextWrapping="{TemplateBinding TextWrapping}" + LineHeight="{TemplateBinding LineHeight}" + PasswordChar="{TemplateBinding PasswordChar}" + RevealPassword="{TemplateBinding RevealPassword}" + SelectionBrush="{TemplateBinding SelectionBrush}" + SelectionForegroundBrush="{TemplateBinding SelectionForegroundBrush}" + CaretBrush="{TemplateBinding CaretBrush}" + HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" + VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/> diff --git a/src/Artemis.UI.Shared/Styles/TreeView.axaml b/src/Artemis.UI.Shared/Styles/TreeView.axaml index feaf8b6a6..1543c0ef6 100644 --- a/src/Artemis.UI.Shared/Styles/TreeView.axaml +++ b/src/Artemis.UI.Shared/Styles/TreeView.axaml @@ -1,15 +1,15 @@  - + Test - + - + @@ -21,7 +21,7 @@ - + Test @@ -32,17 +32,17 @@ - + - + + + + - - - - - - - - + + + + + + + \ No newline at end of file diff --git a/src/Artemis.UI.Shared/Utilities.cs b/src/Artemis.UI.Shared/Utilities.cs new file mode 100644 index 000000000..35abef7db --- /dev/null +++ b/src/Artemis.UI.Shared/Utilities.cs @@ -0,0 +1,8 @@ +using DryIoc; + +namespace Artemis.UI.Shared; + +internal static class UI +{ + public static IContainer Locator { get; set; } = null!; +} \ No newline at end of file diff --git a/src/Artemis.UI.Windows/App.axaml.cs b/src/Artemis.UI.Windows/App.axaml.cs index 9444327c6..617858fb9 100644 --- a/src/Artemis.UI.Windows/App.axaml.cs +++ b/src/Artemis.UI.Windows/App.axaml.cs @@ -13,7 +13,7 @@ using Avalonia; using Avalonia.Controls; using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Markup.Xaml; -using Avalonia.Threading; +using Avalonia.ReactiveUI; using DryIoc; using ReactiveUI; diff --git a/src/Artemis.UI.Windows/Artemis.UI.Windows.csproj b/src/Artemis.UI.Windows/Artemis.UI.Windows.csproj index 96d6d57fb..7b9c44ee8 100644 --- a/src/Artemis.UI.Windows/Artemis.UI.Windows.csproj +++ b/src/Artemis.UI.Windows/Artemis.UI.Windows.csproj @@ -1,7 +1,7 @@  WinExe - net6.0-windows10.0.17763.0 + net7.0-windows10.0.17763.0 enable x64 bin @@ -21,18 +21,18 @@ - - + + - - - - + + + + - - - - + + + + diff --git a/src/Artemis.UI.Windows/Properties/launchSettings.json b/src/Artemis.UI.Windows/Properties/launchSettings.json index a1588c6f9..cb8118713 100644 --- a/src/Artemis.UI.Windows/Properties/launchSettings.json +++ b/src/Artemis.UI.Windows/Properties/launchSettings.json @@ -2,7 +2,7 @@ "profiles": { "Artemis.UI.Windows": { "commandName": "Project", - "commandLineArgs": "--force-elevation --disable-forced-shutdown --pcmr" + "commandLineArgs": "--disable-forced-shutdown --pcmr" } } } \ No newline at end of file diff --git a/src/Artemis.UI.Windows/Providers/Input/SpongeWindow.cs b/src/Artemis.UI.Windows/Providers/Input/SpongeWindow.cs deleted file mode 100644 index ec8f6d04b..000000000 --- a/src/Artemis.UI.Windows/Providers/Input/SpongeWindow.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System; -using Avalonia.Win32; - -namespace Artemis.UI.Windows.Providers.Input; - -public class SpongeWindow : WindowImpl -{ - public event EventHandler? WndProcCalled; - - #region Overrides of WindowImpl - - /// - protected override IntPtr WndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam) - { - OnWndProcCalled(new SpongeWindowEventArgs(hWnd, msg, wParam, lParam)); - return base.WndProc(hWnd, msg, wParam, lParam); - } - - #endregion - - protected virtual void OnWndProcCalled(SpongeWindowEventArgs e) - { - WndProcCalled?.Invoke(this, e); - } -} \ No newline at end of file diff --git a/src/Artemis.UI.Windows/Providers/Input/SpongeWindowEventArgs.cs b/src/Artemis.UI.Windows/Providers/Input/SpongeWindowEventArgs.cs deleted file mode 100644 index 507b42d8c..000000000 --- a/src/Artemis.UI.Windows/Providers/Input/SpongeWindowEventArgs.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System; - -namespace Artemis.UI.Windows.Providers.Input; - -public class SpongeWindowEventArgs : EventArgs -{ - public SpongeWindowEventArgs(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam) - { - HWnd = hWnd; - Msg = msg; - WParam = wParam; - LParam = lParam; - } - - public IntPtr HWnd { get; } - public uint Msg { get; } - public IntPtr WParam { get; } - public IntPtr LParam { get; } -} \ No newline at end of file diff --git a/src/Artemis.UI.Windows/Providers/Input/WindowsInputProvider.cs b/src/Artemis.UI.Windows/Providers/Input/WindowsInputProvider.cs index 2c375b3e4..40f51d132 100644 --- a/src/Artemis.UI.Windows/Providers/Input/WindowsInputProvider.cs +++ b/src/Artemis.UI.Windows/Providers/Input/WindowsInputProvider.cs @@ -5,6 +5,8 @@ using System.Timers; using Artemis.Core; using Artemis.Core.Services; using Artemis.UI.Windows.Utilities; +using Avalonia.Controls.Platform; +using Avalonia.Platform; using Linearstar.Windows.RawInput; using Linearstar.Windows.RawInput.Native; using Serilog; @@ -13,28 +15,43 @@ namespace Artemis.UI.Windows.Providers.Input; public class WindowsInputProvider : InputProvider { + private const int GWL_WNDPROC = -4; private const int WM_INPUT = 0x00FF; + private readonly IWindowImpl _window; + private readonly nint _hWndProcHook; + private readonly WndProc? _fnWndProcHook; private readonly IInputService _inputService; private readonly ILogger _logger; - private readonly SpongeWindow _sponge; private readonly Timer _taskManagerTimer; + private int _lastProcessId; + delegate nint WndProc(nint hWnd, uint msg, nint wParam, nint lParam); + + private nint CustomWndProc(nint hWnd, uint msg, nint wParam, nint lParam) + { + OnWndProcCalled(hWnd, msg, wParam, lParam); + return CallWindowProc(_hWndProcHook, hWnd, msg, wParam, lParam); + } public WindowsInputProvider(ILogger logger, IInputService inputService) { _logger = logger; _inputService = inputService; - _sponge = new SpongeWindow(); - _sponge.WndProcCalled += SpongeOnWndProcCalled; - _taskManagerTimer = new Timer(500); _taskManagerTimer.Elapsed += TaskManagerTimerOnElapsed; _taskManagerTimer.Start(); - RawInputDevice.RegisterDevice(HidUsageAndPage.Keyboard, RawInputDeviceFlags.InputSink, _sponge.Handle.Handle); - RawInputDevice.RegisterDevice(HidUsageAndPage.Mouse, RawInputDeviceFlags.InputSink, _sponge.Handle.Handle); + _window = PlatformManager.CreateWindow(); + + _hWndProcHook = GetWindowLongPtr(_window.Handle.Handle, GWL_WNDPROC); + _fnWndProcHook = CustomWndProc; + nint newLong = Marshal.GetFunctionPointerForDelegate(_fnWndProcHook); + SetWindowLongPtr(_window.Handle.Handle, GWL_WNDPROC, newLong); + + RawInputDevice.RegisterDevice(HidUsageAndPage.Keyboard, RawInputDeviceFlags.InputSink, _window.Handle.Handle); + RawInputDevice.RegisterDevice(HidUsageAndPage.Mouse, RawInputDeviceFlags.InputSink, _window.Handle.Handle); } public static Guid Id { get; } = new("6737b204-ffb1-4cd9-8776-9fb851db303a"); @@ -55,19 +72,18 @@ public class WindowsInputProvider : InputProvider { if (disposing) { - _sponge.Dispose(); _taskManagerTimer.Dispose(); } base.Dispose(disposing); } - private void SpongeOnWndProcCalled(object? sender, SpongeWindowEventArgs message) + private void OnWndProcCalled(nint hWnd, uint msg, nint wParam, nint lParam) { - if (message.Msg != WM_INPUT) + if (msg != WM_INPUT) return; - RawInputData data = RawInputData.FromHandle(message.LParam); + RawInputData data = RawInputData.FromHandle(lParam); switch (data) { case RawInputMouseData mouse: @@ -221,6 +237,15 @@ public class WindowsInputProvider : InputProvider #region Native + [DllImport("user32.dll", CharSet = CharSet.Unicode)] + static extern IntPtr CallWindowProc(nint lpPrevWndFunc, IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam); + + [DllImport("user32.dll", EntryPoint = "GetWindowLongPtr", CharSet = CharSet.Unicode)] + private static extern IntPtr GetWindowLongPtr(IntPtr hWnd, int nIndex); + + [DllImport("user32.dll", EntryPoint = "SetWindowLongPtr", CharSet = CharSet.Unicode)] + private static extern IntPtr SetWindowLongPtr(nint hWnd, int nIndex, IntPtr dwNewLong); + [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool GetCursorPos(ref Win32Point pt); diff --git a/src/Artemis.UI.Windows/Providers/WindowsUpdateNotificationProvider.cs b/src/Artemis.UI.Windows/Providers/WindowsUpdateNotificationProvider.cs index 7af9d6927..f77ee9226 100644 --- a/src/Artemis.UI.Windows/Providers/WindowsUpdateNotificationProvider.cs +++ b/src/Artemis.UI.Windows/Providers/WindowsUpdateNotificationProvider.cs @@ -9,7 +9,6 @@ using Artemis.UI.Screens.Settings; using Artemis.UI.Services.Updating; using Artemis.UI.Shared.Services.MainWindow; using Avalonia.Threading; -using DryIoc.ImTools; using Microsoft.Toolkit.Uwp.Notifications; using ReactiveUI; diff --git a/src/Artemis.UI.Windows/SkiaSharp/Vulkan/Win32VkContext.cs b/src/Artemis.UI.Windows/SkiaSharp/Vulkan/Win32VkContext.cs index 7c95696c3..7ebb48a16 100644 --- a/src/Artemis.UI.Windows/SkiaSharp/Vulkan/Win32VkContext.cs +++ b/src/Artemis.UI.Windows/SkiaSharp/Vulkan/Win32VkContext.cs @@ -1,6 +1,7 @@ using System; using System.Linq; -using Avalonia.Win32; +using Avalonia.Controls.Platform; +using Avalonia.Platform; using SharpVk; using SharpVk.Khronos; @@ -10,7 +11,7 @@ internal sealed class Win32VkContext : VkContext { public Win32VkContext() { - Window = new WindowImpl(); + Window = PlatformManager.CreateWindow(); Instance = Instance.Create(null, new[] {"VK_KHR_surface", "VK_KHR_win32_surface"}); PhysicalDevice = Instance.EnumeratePhysicalDevices().First(); Surface = Instance.CreateWin32Surface(Kernel32.CurrentModuleHandle, Window.Handle.Handle); @@ -43,7 +44,7 @@ internal sealed class Win32VkContext : VkContext }; } - public WindowImpl Window { get; } + public IWindowImpl Window { get; } public override void Dispose() { diff --git a/src/Artemis.UI/Artemis.UI.csproj b/src/Artemis.UI/Artemis.UI.csproj index e2619345d..4e6b4e383 100644 --- a/src/Artemis.UI/Artemis.UI.csproj +++ b/src/Artemis.UI/Artemis.UI.csproj @@ -1,7 +1,7 @@ Library - net6.0 + net7.0 enable bin/ x64 @@ -15,29 +15,28 @@ - - - - - + + + + - - - - - - + + + + + + - - - - - - - - - + + + + + + + + + diff --git a/src/Artemis.UI/Artemis.UI.csproj.DotSettings b/src/Artemis.UI/Artemis.UI.csproj.DotSettings index 9b01cf388..e73de0af9 100644 --- a/src/Artemis.UI/Artemis.UI.csproj.DotSettings +++ b/src/Artemis.UI/Artemis.UI.csproj.DotSettings @@ -1,4 +1,5 @@ - + True True True diff --git a/src/Artemis.UI/Behaviors/SimpleContextDragBehavior.cs b/src/Artemis.UI/Behaviors/SimpleContextDragBehavior.cs index 940527c75..bd3845bfa 100644 --- a/src/Artemis.UI/Behaviors/SimpleContextDragBehavior.cs +++ b/src/Artemis.UI/Behaviors/SimpleContextDragBehavior.cs @@ -106,7 +106,7 @@ public class SimpleContextDragBehavior : Behavior PointerPointProperties properties = e.GetCurrentPoint(AssociatedObject).Properties; if (!properties.IsLeftButtonPressed || FocusManager.Instance?.Current is TextBox) return; - if (e.Source is not IControl control || AssociatedObject?.DataContext != control.DataContext) + if (e.Source is not Control control || AssociatedObject?.DataContext != control.DataContext) return; _dragStartPoint = e.GetPosition(null); diff --git a/src/Artemis.UI/Behaviors/TreeItemDragBehavior.cs b/src/Artemis.UI/Behaviors/TreeItemDragBehavior.cs index d06518912..3276d8d17 100644 --- a/src/Artemis.UI/Behaviors/TreeItemDragBehavior.cs +++ b/src/Artemis.UI/Behaviors/TreeItemDragBehavior.cs @@ -2,7 +2,6 @@ using System.Collections; using Avalonia; using Avalonia.Controls; -using Avalonia.Controls.Generators; using Avalonia.Controls.Primitives; using Avalonia.Input; using Avalonia.Interactivity; @@ -14,7 +13,7 @@ namespace Artemis.UI.Behaviors; /// /// -public class TreeItemDragBehavior : Behavior +public class TreeItemDragBehavior : Behavior { /// /// @@ -31,7 +30,7 @@ public class TreeItemDragBehavior : Behavior public static readonly StyledProperty VerticalDragThresholdProperty = AvaloniaProperty.Register(nameof(VerticalDragThreshold), 3); - private IControl? _draggedContainer; + private Control? _draggedContainer; private int _draggedIndex; private bool _dragStarted; private bool _enableDrag; @@ -69,12 +68,12 @@ public class TreeItemDragBehavior : Behavior { base.OnAttached(); - if (AssociatedObject is { }) + if (AssociatedObject is not null) { - AssociatedObject.AddHandler(InputElement.PointerReleasedEvent, Released, RoutingStrategies.Tunnel); - AssociatedObject.AddHandler(InputElement.PointerPressedEvent, Pressed, RoutingStrategies.Tunnel); - AssociatedObject.AddHandler(InputElement.PointerMovedEvent, Moved, RoutingStrategies.Tunnel); - AssociatedObject.AddHandler(InputElement.PointerCaptureLostEvent, CaptureLost, RoutingStrategies.Tunnel); + AssociatedObject.AddHandler(InputElement.PointerReleasedEvent, ReleasedHandler, RoutingStrategies.Tunnel); + AssociatedObject.AddHandler(InputElement.PointerPressedEvent, PressedHandler, RoutingStrategies.Tunnel); + AssociatedObject.AddHandler(InputElement.PointerMovedEvent, MovedHandler, RoutingStrategies.Tunnel); + AssociatedObject.AddHandler(InputElement.PointerCaptureLostEvent, CaptureLostHandler, RoutingStrategies.Tunnel); } } @@ -84,16 +83,16 @@ public class TreeItemDragBehavior : Behavior { base.OnDetaching(); - if (AssociatedObject is { }) + if (AssociatedObject is not null) { - AssociatedObject.RemoveHandler(InputElement.PointerReleasedEvent, Released); - AssociatedObject.RemoveHandler(InputElement.PointerPressedEvent, Pressed); - AssociatedObject.RemoveHandler(InputElement.PointerMovedEvent, Moved); - AssociatedObject.RemoveHandler(InputElement.PointerCaptureLostEvent, CaptureLost); + AssociatedObject.RemoveHandler(InputElement.PointerReleasedEvent, ReleasedHandler); + AssociatedObject.RemoveHandler(InputElement.PointerPressedEvent, PressedHandler); + AssociatedObject.RemoveHandler(InputElement.PointerMovedEvent, MovedHandler); + AssociatedObject.RemoveHandler(InputElement.PointerCaptureLostEvent, CaptureLostHandler); } } - private void Pressed(object? sender, PointerPressedEventArgs e) + private void PressedHandler(object? sender, PointerPressedEventArgs e) { PointerPointProperties properties = e.GetCurrentPoint(AssociatedObject).Properties; if (properties.IsLeftButtonPressed @@ -101,20 +100,20 @@ public class TreeItemDragBehavior : Behavior { _enableDrag = true; _dragStarted = false; - _start = e.GetPosition(AssociatedObject.Parent); + _start = e.GetPosition(AssociatedObject.Parent as Visual); _draggedIndex = -1; _targetIndex = -1; _itemsControl = itemsControl; _draggedContainer = AssociatedObject; - if (_draggedContainer is { }) + if (_draggedContainer is not null) SetDraggingPseudoClasses(_draggedContainer, true); AddTransforms(_itemsControl); } } - private void Released(object? sender, PointerReleasedEventArgs e) + private void ReleasedHandler(object? sender, PointerReleasedEventArgs e) { if (_dragStarted) { @@ -125,7 +124,7 @@ public class TreeItemDragBehavior : Behavior } } - private void CaptureLost(object? sender, PointerCaptureLostEventArgs e) + private void CaptureLostHandler(object? sender, PointerCaptureLostEventArgs e) { Released(); } @@ -137,19 +136,23 @@ public class TreeItemDragBehavior : Behavior RemoveTransforms(_itemsControl); - if (_itemsControl is { }) - foreach (ItemContainerInfo? container in _itemsControl.ItemContainerGenerator.Containers) - SetDraggingPseudoClasses(container.ContainerControl, true); + if (_itemsControl is not null) + { + foreach (Control realizedContainer in _itemsControl.GetRealizedContainers()) + SetDraggingPseudoClasses(realizedContainer, true); + } if (_dragStarted) if (_draggedIndex >= 0 && _targetIndex >= 0 && _draggedIndex != _targetIndex) MoveDraggedItem(_itemsControl, _draggedIndex, _targetIndex); - if (_itemsControl is { }) - foreach (ItemContainerInfo? container in _itemsControl.ItemContainerGenerator.Containers) - SetDraggingPseudoClasses(container.ContainerControl, false); + if (_itemsControl is not null) + { + foreach (Control realizedContainer in _itemsControl.GetRealizedContainers()) + SetDraggingPseudoClasses(realizedContainer, false); + } - if (_draggedContainer is { }) + if (_draggedContainer is not null) SetDraggingPseudoClasses(_draggedContainer, false); _draggedIndex = -1; @@ -165,17 +168,9 @@ public class TreeItemDragBehavior : Behavior { if (itemsControl?.Items is null) return; - - int i = 0; - - foreach (object? _ in itemsControl.Items) - { - IControl? container = itemsControl.ItemContainerGenerator.ContainerFromIndex(i); - if (container is not null) - SetTranslateTransform(container, 0, 0); - - i++; - } + + foreach (Control container in itemsControl.GetRealizedContainers()) + SetTranslateTransform(container, 0, 0); } private void RemoveTransforms(ItemsControl? itemsControl) @@ -183,16 +178,8 @@ public class TreeItemDragBehavior : Behavior if (itemsControl?.Items is null) return; - int i = 0; - - foreach (object? _ in itemsControl.Items) - { - IControl? container = itemsControl.ItemContainerGenerator.ContainerFromIndex(i); - if (container is not null) - SetTranslateTransform(container, 0, 0); - - i++; - } + foreach (Control container in itemsControl.GetRealizedContainers()) + SetTranslateTransform(container, 0, 0); } private void MoveDraggedItem(ItemsControl? itemsControl, int draggedIndex, int targetIndex) @@ -208,7 +195,7 @@ public class TreeItemDragBehavior : Behavior selectingItemsControl.SelectedIndex = targetIndex; } - private void Moved(object? sender, PointerEventArgs e) + private void MovedHandler(object? sender, PointerEventArgs e) { PointerPointProperties properties = e.GetCurrentPoint(AssociatedObject).Properties; if (properties.IsLeftButtonPressed) @@ -249,7 +236,7 @@ public class TreeItemDragBehavior : Behavior else SetTranslateTransform(_draggedContainer, 0, delta); - _draggedIndex = _itemsControl.ItemContainerGenerator.IndexFromContainer(_draggedContainer); + _draggedIndex = _itemsControl.IndexFromContainer(_draggedContainer); _targetIndex = -1; Rect draggedBounds = _draggedContainer.Bounds; @@ -263,17 +250,11 @@ public class TreeItemDragBehavior : Behavior double draggedDeltaEnd = orientation == Orientation.Horizontal ? draggedBounds.X + delta + draggedBounds.Width : draggedBounds.Y + delta + draggedBounds.Height; - - int i = 0; - - foreach (object? _ in _itemsControl.Items) + + foreach (Control targetContainer in _itemsControl.GetRealizedContainers()) { - IControl? targetContainer = _itemsControl.ItemContainerGenerator.ContainerFromIndex(i); - if (targetContainer?.RenderTransform is null || ReferenceEquals(targetContainer, _draggedContainer)) - { - i++; + if (targetContainer.RenderTransform is null || ReferenceEquals(targetContainer, _draggedContainer)) continue; - } // If the target container has children, there are two options // Move into the top of the container @@ -286,7 +267,7 @@ public class TreeItemDragBehavior : Behavior ? targetBounds.X + targetBounds.Width / 2 : targetBounds.Y + targetBounds.Height / 2; - int targetIndex = _itemsControl.ItemContainerGenerator.IndexFromContainer(targetContainer); + int targetIndex = _itemsControl.IndexFromContainer(targetContainer); if (targetStart > draggedStart && draggedDeltaEnd >= targetMid) { @@ -315,22 +296,24 @@ public class TreeItemDragBehavior : Behavior else SetTranslateTransform(targetContainer, 0, 0); } - - i++; } } } - private void SetDraggingPseudoClasses(IControl control, bool isDragging) + private void SetDraggingPseudoClasses(Control? control, bool isDragging) { + if (control == null) + return; if (isDragging) ((IPseudoClasses) control.Classes).Add(":dragging"); else ((IPseudoClasses) control.Classes).Remove(":dragging"); } - private void SetTranslateTransform(IControl control, double x, double y) + private void SetTranslateTransform(Control? control, double x, double y) { + if (control == null) + return; TransformOperations.Builder transformBuilder = new(1); transformBuilder.AppendTranslate(x, y); control.RenderTransform = transformBuilder.Build(); diff --git a/src/Artemis.UI/Controls/TimelineHeader.cs b/src/Artemis.UI/Controls/TimelineHeader.cs index e0ecc3593..03968b234 100644 --- a/src/Artemis.UI/Controls/TimelineHeader.cs +++ b/src/Artemis.UI/Controls/TimelineHeader.cs @@ -1,4 +1,5 @@ using System; +using System.Globalization; using Avalonia; using Avalonia.Controls; using Avalonia.Media; @@ -137,47 +138,47 @@ public class TimelineHeader : Control private void RenderLabel(DrawingContext drawingContext, string text, double x) { Typeface typeFace = new(FontFamily); - FormattedText formattedText = new(text, typeFace, 9, TextAlignment.Left, TextWrapping.NoWrap, Bounds.Size); + FormattedText formattedText = new(text, CultureInfo.CurrentCulture, FlowDirection.LeftToRight, typeFace, 9, Foreground); if (x == 0 && OffsetFirstValue) - drawingContext.DrawText(Foreground, new Point(2, 5), formattedText); + drawingContext.DrawText(formattedText, new Point(2, 5)); else - drawingContext.DrawText(Foreground, new Point(x - formattedText.Bounds.Width / 2, 5), formattedText); + drawingContext.DrawText(formattedText, new Point(x - formattedText.Width / 2, 5)); } private void UpdateTimeScale() { - object[] subds; + double[] subds; if (PixelsPerSecond > 350) - subds = new object[] {12d, 12d, 60d}; + subds = new[] {12d, 12d, 60d}; else if (PixelsPerSecond > 250) - subds = new object[] {6d, 12d, 60d}; + subds = new[] {6d, 12d, 60d}; else if (PixelsPerSecond > 200) - subds = new object[] {6d, 6d, 30d}; + subds = new[] {6d, 6d, 30d}; else if (PixelsPerSecond > 150) - subds = new object[] {4d, 4d, 20d}; + subds = new[] {4d, 4d, 20d}; else if (PixelsPerSecond > 140) - subds = new object[] {4d, 4d, 20d}; + subds = new[] {4d, 4d, 20d}; else if (PixelsPerSecond > 90) - subds = new object[] {2d, 4d, 20d}; + subds = new[] {2d, 4d, 20d}; else if (PixelsPerSecond > 60) - subds = new object[] {2d, 4d, 8d}; + subds = new[] {2d, 4d, 8d}; else if (PixelsPerSecond > 40) - subds = new object[] {1d, 2d, 10d}; + subds = new[] {1d, 2d, 10d}; else if (PixelsPerSecond > 30) - subds = new object[] {1d, 2d, 10d}; + subds = new[] {1d, 2d, 10d}; else if (PixelsPerSecond > 10) - subds = new object[] {1d / 2d, 1d / 2d, 1d / 2d}; + subds = new[] {1d / 2d, 1d / 2d, 1d / 2d}; else if (PixelsPerSecond > 4) - subds = new object[] {1d / 5d, 1d / 5d, 1d / 5d}; + subds = new[] {1d / 5d, 1d / 5d, 1d / 5d}; else if (PixelsPerSecond > 3) - subds = new object[] {1d / 10d, 1d / 10d, 1d / 5d}; + subds = new[] {1d / 10d, 1d / 10d, 1d / 5d}; else if (PixelsPerSecond > 1) - subds = new object[] {1d / 20d, 1d / 20d, 1d / 10d}; + subds = new[] {1d / 20d, 1d / 20d, 1d / 10d}; else if (PixelsPerSecond >= 1) - subds = new object[] {1d / 30d, 1d / 30d, 1d / 15d}; + subds = new[] {1d / 30d, 1d / 30d, 1d / 15d}; else // 1s per pixel - subds = new object[] {1d / 60d, 1d / 60d, 1d / 15d}; + subds = new[] {1d / 60d, 1d / 60d, 1d / 15d}; _subd1 = (double) subds[0]; // big ticks / labels _subd2 = (double) subds[1]; // medium ticks diff --git a/src/Artemis.UI/DefaultTypes/PropertyInput/BoolPropertyInputView.axaml.cs b/src/Artemis.UI/DefaultTypes/PropertyInput/BoolPropertyInputView.axaml.cs index 624ba9770..66e0f8f66 100644 --- a/src/Artemis.UI/DefaultTypes/PropertyInput/BoolPropertyInputView.axaml.cs +++ b/src/Artemis.UI/DefaultTypes/PropertyInput/BoolPropertyInputView.axaml.cs @@ -3,15 +3,11 @@ using Avalonia.ReactiveUI; namespace Artemis.UI.DefaultTypes.PropertyInput; -public class BoolPropertyInputView : ReactiveUserControl +public partial class BoolPropertyInputView : ReactiveUserControl { public BoolPropertyInputView() { InitializeComponent(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } } \ No newline at end of file diff --git a/src/Artemis.UI/DefaultTypes/PropertyInput/BrushPropertyInputView.axaml.cs b/src/Artemis.UI/DefaultTypes/PropertyInput/BrushPropertyInputView.axaml.cs index 636515d99..c7a542a47 100644 --- a/src/Artemis.UI/DefaultTypes/PropertyInput/BrushPropertyInputView.axaml.cs +++ b/src/Artemis.UI/DefaultTypes/PropertyInput/BrushPropertyInputView.axaml.cs @@ -3,15 +3,11 @@ using Avalonia.ReactiveUI; namespace Artemis.UI.DefaultTypes.PropertyInput; -public class BrushPropertyInputView : ReactiveUserControl +public partial class BrushPropertyInputView : ReactiveUserControl { public BrushPropertyInputView() { InitializeComponent(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } } \ No newline at end of file diff --git a/src/Artemis.UI/DefaultTypes/PropertyInput/BrushPropertyInputViewModel.cs b/src/Artemis.UI/DefaultTypes/PropertyInput/BrushPropertyInputViewModel.cs index 8f9ae6277..92321d8a0 100644 --- a/src/Artemis.UI/DefaultTypes/PropertyInput/BrushPropertyInputViewModel.cs +++ b/src/Artemis.UI/DefaultTypes/PropertyInput/BrushPropertyInputViewModel.cs @@ -1,6 +1,7 @@ using System; using System.Collections.ObjectModel; using System.Linq; +using System.Reactive.Disposables; using System.Reactive.Linq; using Artemis.Core; using Artemis.Core.LayerBrushes; @@ -11,7 +12,6 @@ using Artemis.UI.Shared.Services.Builders; using Artemis.UI.Shared.Services.ProfileEditor; using Artemis.UI.Shared.Services.ProfileEditor.Commands; using Artemis.UI.Shared.Services.PropertyInput; -using Avalonia.Controls.Mixins; using Avalonia.Threading; using ReactiveUI; diff --git a/src/Artemis.UI/DefaultTypes/PropertyInput/ColorGradientPropertyInputView.axaml.cs b/src/Artemis.UI/DefaultTypes/PropertyInput/ColorGradientPropertyInputView.axaml.cs index 2288a4821..e41460b0a 100644 --- a/src/Artemis.UI/DefaultTypes/PropertyInput/ColorGradientPropertyInputView.axaml.cs +++ b/src/Artemis.UI/DefaultTypes/PropertyInput/ColorGradientPropertyInputView.axaml.cs @@ -5,17 +5,13 @@ using Avalonia.ReactiveUI; namespace Artemis.UI.DefaultTypes.PropertyInput; -public class ColorGradientPropertyInputView : ReactiveUserControl +public partial class ColorGradientPropertyInputView : ReactiveUserControl { public ColorGradientPropertyInputView() { InitializeComponent(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } private void GradientPickerButton_OnFlyoutOpened(GradientPickerButton sender, EventArgs args) { diff --git a/src/Artemis.UI/DefaultTypes/PropertyInput/EnumPropertyInputView.axaml.cs b/src/Artemis.UI/DefaultTypes/PropertyInput/EnumPropertyInputView.axaml.cs index 60eab4443..d5bd57b96 100644 --- a/src/Artemis.UI/DefaultTypes/PropertyInput/EnumPropertyInputView.axaml.cs +++ b/src/Artemis.UI/DefaultTypes/PropertyInput/EnumPropertyInputView.axaml.cs @@ -4,15 +4,11 @@ using Avalonia.ReactiveUI; namespace Artemis.UI.DefaultTypes.PropertyInput; -public class EnumPropertyInputView : ReactiveUserControl +public partial class EnumPropertyInputView : ReactiveUserControl { public EnumPropertyInputView() { InitializeComponent(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } } \ No newline at end of file diff --git a/src/Artemis.UI/DefaultTypes/PropertyInput/FloatPropertyInputView.axaml.cs b/src/Artemis.UI/DefaultTypes/PropertyInput/FloatPropertyInputView.axaml.cs index 631a05329..f9ef0b669 100644 --- a/src/Artemis.UI/DefaultTypes/PropertyInput/FloatPropertyInputView.axaml.cs +++ b/src/Artemis.UI/DefaultTypes/PropertyInput/FloatPropertyInputView.axaml.cs @@ -5,17 +5,13 @@ using Avalonia.ReactiveUI; namespace Artemis.UI.DefaultTypes.PropertyInput; -public class FloatPropertyInputView : ReactiveUserControl +public partial class FloatPropertyInputView : ReactiveUserControl { public FloatPropertyInputView() { InitializeComponent(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } private void DraggableNumberBox_OnDragStarted(DraggableNumberBox sender, EventArgs args) { diff --git a/src/Artemis.UI/DefaultTypes/PropertyInput/FloatRangePropertyInputView.axaml.cs b/src/Artemis.UI/DefaultTypes/PropertyInput/FloatRangePropertyInputView.axaml.cs index a297da606..5567c1cee 100644 --- a/src/Artemis.UI/DefaultTypes/PropertyInput/FloatRangePropertyInputView.axaml.cs +++ b/src/Artemis.UI/DefaultTypes/PropertyInput/FloatRangePropertyInputView.axaml.cs @@ -5,17 +5,13 @@ using Avalonia.ReactiveUI; namespace Artemis.UI.DefaultTypes.PropertyInput; -public class FloatRangePropertyInputView : ReactiveUserControl +public partial class FloatRangePropertyInputView : ReactiveUserControl { public FloatRangePropertyInputView() { InitializeComponent(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } private void DraggableNumberBox_OnDragStarted(DraggableNumberBox sender, EventArgs args) { diff --git a/src/Artemis.UI/DefaultTypes/PropertyInput/IntPropertyInputView.axaml.cs b/src/Artemis.UI/DefaultTypes/PropertyInput/IntPropertyInputView.axaml.cs index e1afcd555..5e06c0aea 100644 --- a/src/Artemis.UI/DefaultTypes/PropertyInput/IntPropertyInputView.axaml.cs +++ b/src/Artemis.UI/DefaultTypes/PropertyInput/IntPropertyInputView.axaml.cs @@ -5,17 +5,13 @@ using Avalonia.ReactiveUI; namespace Artemis.UI.DefaultTypes.PropertyInput; -public class IntPropertyInputView : ReactiveUserControl +public partial class IntPropertyInputView : ReactiveUserControl { public IntPropertyInputView() { InitializeComponent(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } private void DraggableNumberBox_OnDragStarted(DraggableNumberBox sender, EventArgs args) { diff --git a/src/Artemis.UI/DefaultTypes/PropertyInput/IntRangePropertyInputView.axaml.cs b/src/Artemis.UI/DefaultTypes/PropertyInput/IntRangePropertyInputView.axaml.cs index 6aff0155f..a703040f4 100644 --- a/src/Artemis.UI/DefaultTypes/PropertyInput/IntRangePropertyInputView.axaml.cs +++ b/src/Artemis.UI/DefaultTypes/PropertyInput/IntRangePropertyInputView.axaml.cs @@ -5,17 +5,13 @@ using Avalonia.ReactiveUI; namespace Artemis.UI.DefaultTypes.PropertyInput; -public class IntRangePropertyInputView : ReactiveUserControl +public partial class IntRangePropertyInputView : ReactiveUserControl { public IntRangePropertyInputView() { InitializeComponent(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } private void DraggableNumberBox_OnDragStarted(DraggableNumberBox sender, EventArgs args) { diff --git a/src/Artemis.UI/DefaultTypes/PropertyInput/SKColorPropertyInputView.axaml b/src/Artemis.UI/DefaultTypes/PropertyInput/SKColorPropertyInputView.axaml index 2662f793b..622178c7b 100644 --- a/src/Artemis.UI/DefaultTypes/PropertyInput/SKColorPropertyInputView.axaml +++ b/src/Artemis.UI/DefaultTypes/PropertyInput/SKColorPropertyInputView.axaml @@ -5,6 +5,7 @@ xmlns:controls="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia" xmlns:propertyInput="clr-namespace:Artemis.UI.DefaultTypes.PropertyInput" xmlns:shared="clr-namespace:Artemis.UI.Shared.Converters;assembly=Artemis.UI.Shared" + xmlns:behaviors="clr-namespace:Artemis.UI.Shared.Behaviors;assembly=Artemis.UI.Shared" mc:Ignorable="d" d:DesignWidth="200" d:DesignHeight="450" x:Class="Artemis.UI.DefaultTypes.PropertyInput.SKColorPropertyInputView" x:DataType="propertyInput:SKColorPropertyInputViewModel"> @@ -13,13 +14,15 @@ - + + + + diff --git a/src/Artemis.UI/DefaultTypes/PropertyInput/SKColorPropertyInputView.axaml.cs b/src/Artemis.UI/DefaultTypes/PropertyInput/SKColorPropertyInputView.axaml.cs index 50b3c150e..83d3c91fe 100644 --- a/src/Artemis.UI/DefaultTypes/PropertyInput/SKColorPropertyInputView.axaml.cs +++ b/src/Artemis.UI/DefaultTypes/PropertyInput/SKColorPropertyInputView.axaml.cs @@ -5,17 +5,13 @@ using FluentAvalonia.UI.Controls; namespace Artemis.UI.DefaultTypes.PropertyInput; -public class SKColorPropertyInputView : ReactiveUserControl +public partial class SKColorPropertyInputView : ReactiveUserControl { public SKColorPropertyInputView() { InitializeComponent(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } private void ColorPickerButton_OnFlyoutOpened(ColorPickerButton sender, EventArgs args) { diff --git a/src/Artemis.UI/DefaultTypes/PropertyInput/SKPointPropertyInputView.axaml.cs b/src/Artemis.UI/DefaultTypes/PropertyInput/SKPointPropertyInputView.axaml.cs index 4cfeefd97..5b707d3bd 100644 --- a/src/Artemis.UI/DefaultTypes/PropertyInput/SKPointPropertyInputView.axaml.cs +++ b/src/Artemis.UI/DefaultTypes/PropertyInput/SKPointPropertyInputView.axaml.cs @@ -5,17 +5,13 @@ using Avalonia.ReactiveUI; namespace Artemis.UI.DefaultTypes.PropertyInput; -public class SKPointPropertyInputView : ReactiveUserControl +public partial class SKPointPropertyInputView : ReactiveUserControl { public SKPointPropertyInputView() { InitializeComponent(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } private void DraggableNumberBox_OnDragStarted(DraggableNumberBox sender, EventArgs args) { diff --git a/src/Artemis.UI/DefaultTypes/PropertyInput/SKSizePropertyInputView.axaml.cs b/src/Artemis.UI/DefaultTypes/PropertyInput/SKSizePropertyInputView.axaml.cs index 9773b8daa..d4eb6fb41 100644 --- a/src/Artemis.UI/DefaultTypes/PropertyInput/SKSizePropertyInputView.axaml.cs +++ b/src/Artemis.UI/DefaultTypes/PropertyInput/SKSizePropertyInputView.axaml.cs @@ -5,17 +5,13 @@ using Avalonia.ReactiveUI; namespace Artemis.UI.DefaultTypes.PropertyInput; -public class SKSizePropertyInputView : ReactiveUserControl +public partial class SKSizePropertyInputView : ReactiveUserControl { public SKSizePropertyInputView() { InitializeComponent(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } private void DraggableNumberBox_OnDragStarted(DraggableNumberBox sender, EventArgs args) { diff --git a/src/Artemis.UI/DefaultTypes/PropertyInput/StringPropertyInputView.axaml.cs b/src/Artemis.UI/DefaultTypes/PropertyInput/StringPropertyInputView.axaml.cs index 53d0c00b0..1ef4838a8 100644 --- a/src/Artemis.UI/DefaultTypes/PropertyInput/StringPropertyInputView.axaml.cs +++ b/src/Artemis.UI/DefaultTypes/PropertyInput/StringPropertyInputView.axaml.cs @@ -4,7 +4,7 @@ using Avalonia.ReactiveUI; namespace Artemis.UI.DefaultTypes.PropertyInput; -public class StringPropertyInputView : ReactiveUserControl +public partial class StringPropertyInputView : ReactiveUserControl { public StringPropertyInputView() { @@ -12,10 +12,6 @@ public class StringPropertyInputView : ReactiveUserControl + + + + + + - @@ -19,11 +29,11 @@ - - + + - \ No newline at end of file + \ No newline at end of file diff --git a/src/Artemis.UI/MainWindow.axaml.cs b/src/Artemis.UI/MainWindow.axaml.cs index 336bfb46a..38c92d921 100644 --- a/src/Artemis.UI/MainWindow.axaml.cs +++ b/src/Artemis.UI/MainWindow.axaml.cs @@ -7,16 +7,13 @@ using Artemis.UI.Shared; using Avalonia; using Avalonia.Controls; using Avalonia.Markup.Xaml; -using Avalonia.Threading; -using FluentAvalonia.Core.ApplicationModel; +using Avalonia.ReactiveUI; using ReactiveUI; namespace Artemis.UI; -public class MainWindow : ReactiveCoreWindow +public partial class MainWindow : ReactiveAppWindow { - private readonly Panel _rootPanel; - private readonly ContentControl _sidebarContentControl; private bool _activated; public MainWindow() @@ -25,12 +22,10 @@ public class MainWindow : ReactiveCoreWindow Activated += OnActivated; Deactivated += OnDeactivated; - ApplyWindowSize(); InitializeComponent(); - - _rootPanel = this.Get("RootPanel"); - _sidebarContentControl = this.Get("SidebarContentControl"); - _rootPanel.LayoutUpdated += OnLayoutUpdated; + ApplyWindowSize(); + + RootPanel.LayoutUpdated += OnLayoutUpdated; #if DEBUG this.AttachDevTools(); @@ -57,22 +52,16 @@ public class MainWindow : ReactiveCoreWindow RootViewModel.WindowSizeSetting.Value ??= new WindowSize(); RootViewModel.WindowSizeSetting.Value.ApplyFromWindow(this); } - - // TODO: Replace with a media query once https://github.com/AvaloniaUI/Avalonia/pull/7938 is implemented + private void OnLayoutUpdated(object? sender, EventArgs e) { - _sidebarContentControl.Width = _rootPanel.Bounds.Width >= 1800 ? 300 : 240; + SidebarContentControl.Width = RootPanel.Bounds.Width >= 1800 ? 300 : 240; } private void OnOpened(object? sender, EventArgs e) { Opened -= OnOpened; - ICoreApplicationView coreAppTitleBar = this; - if (coreAppTitleBar.TitleBar != null) - { - coreAppTitleBar.TitleBar.ExtendViewIntoTitleBar = true; - SetTitleBar(this.Get("DragHandle")); - } + TitleBar.ExtendsContentIntoTitleBar = true; } private void OnActivated(object? sender, EventArgs e) @@ -85,8 +74,4 @@ public class MainWindow : ReactiveCoreWindow ViewModel?.Unfocused(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Debugger/DebugView.axaml b/src/Artemis.UI/Screens/Debugger/DebugView.axaml index 6387ce994..26097641e 100644 --- a/src/Artemis.UI/Screens/Debugger/DebugView.axaml +++ b/src/Artemis.UI/Screens/Debugger/DebugView.axaml @@ -1,4 +1,4 @@ - - @@ -38,4 +38,4 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Debugger/DebugView.axaml.cs b/src/Artemis.UI/Screens/Debugger/DebugView.axaml.cs index ed16843c9..6b7f58b7f 100644 --- a/src/Artemis.UI/Screens/Debugger/DebugView.axaml.cs +++ b/src/Artemis.UI/Screens/Debugger/DebugView.axaml.cs @@ -10,7 +10,7 @@ using ReactiveUI; namespace Artemis.UI.Screens.Debugger; -public class DebugView : ReactiveCoreWindow +public partial class DebugView : ReactiveAppWindow { public DebugView() { @@ -29,10 +29,6 @@ public class DebugView : ReactiveCoreWindow }); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } private void DeviceVisualizer_OnLedClicked(object? sender, LedClickedEventArgs e) { diff --git a/src/Artemis.UI/Screens/Debugger/Tabs/DataModel/DataModelDebugView.axaml.cs b/src/Artemis.UI/Screens/Debugger/Tabs/DataModel/DataModelDebugView.axaml.cs index 0e304fc6e..dd39a5f8d 100644 --- a/src/Artemis.UI/Screens/Debugger/Tabs/DataModel/DataModelDebugView.axaml.cs +++ b/src/Artemis.UI/Screens/Debugger/Tabs/DataModel/DataModelDebugView.axaml.cs @@ -3,15 +3,11 @@ using Avalonia.ReactiveUI; namespace Artemis.UI.Screens.Debugger.DataModel; -public class DataModelDebugView : ReactiveUserControl +public partial class DataModelDebugView : ReactiveUserControl { public DataModelDebugView() { InitializeComponent(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Debugger/Tabs/Logs/LogsDebugView.axaml b/src/Artemis.UI/Screens/Debugger/Tabs/Logs/LogsDebugView.axaml index db82a857f..5a5c6d457 100644 --- a/src/Artemis.UI/Screens/Debugger/Tabs/Logs/LogsDebugView.axaml +++ b/src/Artemis.UI/Screens/Debugger/Tabs/Logs/LogsDebugView.axaml @@ -8,19 +8,7 @@ mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" x:Class="Artemis.UI.Screens.Debugger.Logs.LogsDebugView" x:DataType="logs:LogsDebugViewModel"> - - - - - - + + + \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Debugger/Tabs/Logs/LogsDebugView.axaml.cs b/src/Artemis.UI/Screens/Debugger/Tabs/Logs/LogsDebugView.axaml.cs index 9922665fc..219215877 100644 --- a/src/Artemis.UI/Screens/Debugger/Tabs/Logs/LogsDebugView.axaml.cs +++ b/src/Artemis.UI/Screens/Debugger/Tabs/Logs/LogsDebugView.axaml.cs @@ -1,20 +1,16 @@ using System; -using System.Diagnostics; -using System.Reflection; -using Avalonia; using Avalonia.Controls; -using Avalonia.Controls.Primitives; using Avalonia.Markup.Xaml; using Avalonia.ReactiveUI; using Avalonia.Threading; -using AvaloniaEdit; +using ReactiveUI; +using Serilog; namespace Artemis.UI.Screens.Debugger.Logs; -public class LogsDebugView : ReactiveUserControl +public partial class LogsDebugView : ReactiveUserControl { private int _lineCount; - private TextEditor? _textEditor; public LogsDebugView() { @@ -22,47 +18,46 @@ public class LogsDebugView : ReactiveUserControl InitializeComponent(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - _textEditor = this.FindControl("log"); - } protected override void OnInitialized() { base.OnInitialized(); - Dispatcher.UIThread.Post(() => _textEditor?.ScrollToEnd(), DispatcherPriority.ApplicationIdle); + Dispatcher.UIThread.Post(() => LogsScrollViewer.ScrollToEnd(), DispatcherPriority.ApplicationIdle); } - private void OnTextChanged(object? sender, EventArgs e) + // private void OnTextChanged(object? sender, EventArgs e) + // { + // if (LogTextEditor.ExtentHeight == 0) + // return; + // + // int linesAdded = LogTextEditor.LineCount - _lineCount; + // double lineHeight = LogTextEditor.ExtentHeight / LogTextEditor.LineCount; + // double outOfScreenTextHeight = LogTextEditor.ExtentHeight - LogTextEditor.VerticalOffset - LogTextEditor.ViewportHeight; + // double outOfScreenLines = outOfScreenTextHeight / lineHeight; + // + // //we need this help distance because of rounding. + // //if we scroll slightly above the end, we still want it + // //to scroll down to the new lines. + // const double GRACE_DISTANCE = 1d; + // + // //if we were at the bottom of the log and + // //if the last log event was 5 lines long + // //we will be 5 lines out sync. + // //if this is the case, scroll down. + // + // //if we are more than that out of sync, + // //the user scrolled up and we should not + // //mess with anything. + // if (_lineCount == 0 || linesAdded + GRACE_DISTANCE > outOfScreenLines) + // { + // Dispatcher.UIThread.Post(() => LogTextEditor.ScrollToEnd(), DispatcherPriority.ApplicationIdle); + // _lineCount = LogTextEditor.LineCount; + // } + // } + private void Control_OnSizeChanged(object? sender, SizeChangedEventArgs e) { - if (_textEditor is null) + if (!(LogsScrollViewer.Extent.Height - LogsScrollViewer.Offset.Y - LogsScrollViewer.Bounds.Bottom <= 60)) return; - if (_textEditor.ExtentHeight == 0) - return; - - int linesAdded = _textEditor.LineCount - _lineCount; - double lineHeight = _textEditor.ExtentHeight / _textEditor.LineCount; - double outOfScreenTextHeight = _textEditor.ExtentHeight - _textEditor.VerticalOffset - _textEditor.ViewportHeight; - double outOfScreenLines = outOfScreenTextHeight / lineHeight; - - //we need this help distance because of rounding. - //if we scroll slightly above the end, we still want it - //to scroll down to the new lines. - const double GRACE_DISTANCE = 1d; - - //if we were at the bottom of the log and - //if the last log event was 5 lines long - //we will be 5 lines out sync. - //if this is the case, scroll down. - - //if we are more than that out of sync, - //the user scrolled up and we should not - //mess with anything. - if (_lineCount == 0 || linesAdded + GRACE_DISTANCE > outOfScreenLines) - { - Dispatcher.UIThread.Post(() => _textEditor.ScrollToEnd(), DispatcherPriority.ApplicationIdle); - _lineCount = _textEditor.LineCount; - } + Dispatcher.UIThread.Post(() => LogsScrollViewer.ScrollToEnd(), DispatcherPriority.Normal); } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Debugger/Tabs/Logs/LogsDebugViewModel.cs b/src/Artemis.UI/Screens/Debugger/Tabs/Logs/LogsDebugViewModel.cs index c1860b01a..4df1be54e 100644 --- a/src/Artemis.UI/Screens/Debugger/Tabs/Logs/LogsDebugViewModel.cs +++ b/src/Artemis.UI/Screens/Debugger/Tabs/Logs/LogsDebugViewModel.cs @@ -1,12 +1,15 @@ -using Artemis.Core; +using System; +using System.Collections.ObjectModel; +using Artemis.Core; using Artemis.UI.Shared; using Avalonia.Threading; -using AvaloniaEdit.Document; using ReactiveUI; using Serilog.Events; using Serilog.Formatting.Display; using System.IO; using System.Reactive.Disposables; +using Avalonia.Controls.Documents; +using Avalonia.Media; namespace Artemis.UI.Screens.Debugger.Logs; @@ -14,38 +17,32 @@ public class LogsDebugViewModel : ActivatableViewModelBase { private readonly MessageTemplateTextFormatter _formatter; - public TextDocument Document { get; } + public InlineCollection Lines { get; } = new InlineCollection(); private const int MAX_ENTRIES = 1000; - + public LogsDebugViewModel() { DisplayName = "Logs"; - Document = new TextDocument(); + _formatter = new MessageTemplateTextFormatter( "[{Timestamp:yyyy-MM-dd HH:mm:ss.fff}] [{Level:u3}] [{SourceContext}] {Message:lj}{NewLine}{Exception}" ); - foreach(LogEvent logEvent in LogStore.Events) + foreach (LogEvent logEvent in LogStore.Events) AddLogEvent(logEvent); - + this.WhenActivated(disp => - { + { LogStore.EventAdded += OnLogEventAdded; - Disposable.Create(() => - { - LogStore.EventAdded -= OnLogEventAdded; - }).DisposeWith(disp); + Disposable.Create(() => { LogStore.EventAdded -= OnLogEventAdded; }).DisposeWith(disp); }); } private void OnLogEventAdded(object? sender, LogEventEventArgs e) { - Dispatcher.UIThread.Post(() => - { - AddLogEvent(e.LogEvent); - }); + Dispatcher.UIThread.Post(() => { AddLogEvent(e.LogEvent); }); } private void AddLogEvent(LogEvent? logEvent) @@ -56,22 +53,27 @@ public class LogsDebugViewModel : ActivatableViewModelBase using StringWriter writer = new(); _formatter.Format(logEvent, writer); string line = writer.ToString(); - Document.Insert(Document.TextLength, '\n' + line.TrimEnd('\r', '\n')); - while (Document.LineCount > MAX_ENTRIES) - RemoveOldestLine(); + + + Lines.Add(new Run(line.TrimEnd('\r', '\n') + '\n') + { + Foreground = logEvent.Level switch + { + LogEventLevel.Verbose => new SolidColorBrush(Colors.White), + LogEventLevel.Debug => new SolidColorBrush(Color.FromRgb(216, 216, 216)), + LogEventLevel.Information => new SolidColorBrush(Color.FromRgb(93, 201, 255)), + LogEventLevel.Warning => new SolidColorBrush(Color.FromRgb(255, 177, 53)), + LogEventLevel.Error => new SolidColorBrush(Color.FromRgb(255, 63, 63)), + LogEventLevel.Fatal => new SolidColorBrush(Colors.Red), + _ => throw new ArgumentOutOfRangeException() + } + }); + LimitLines(); } - private void RemoveOldestLine() + private void LimitLines() { - int firstNewLine = Document.IndexOf('\n', 0, Document.TextLength); - if (firstNewLine == -1) - { - //this should never happen. - //just in case let's return - //instead of throwing - return; - } - - Document.Remove(0, firstNewLine + 1); + if (Lines.Count > MAX_ENTRIES) + Lines.RemoveRange(0, Lines.Count - MAX_ENTRIES); } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Debugger/Tabs/Performance/PerformanceDebugPluginView.axaml.cs b/src/Artemis.UI/Screens/Debugger/Tabs/Performance/PerformanceDebugPluginView.axaml.cs index bbf87d5e8..27f98c36e 100644 --- a/src/Artemis.UI/Screens/Debugger/Tabs/Performance/PerformanceDebugPluginView.axaml.cs +++ b/src/Artemis.UI/Screens/Debugger/Tabs/Performance/PerformanceDebugPluginView.axaml.cs @@ -3,15 +3,11 @@ using Avalonia.Markup.Xaml; namespace Artemis.UI.Screens.Debugger.Performance; -public class PerformanceDebugPluginView : UserControl +public partial class PerformanceDebugPluginView : UserControl { public PerformanceDebugPluginView() { InitializeComponent(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Debugger/Tabs/Performance/PerformanceDebugProfilerView.axaml b/src/Artemis.UI/Screens/Debugger/Tabs/Performance/PerformanceDebugProfilerView.axaml index d9f712498..27c44a856 100644 --- a/src/Artemis.UI/Screens/Debugger/Tabs/Performance/PerformanceDebugProfilerView.axaml +++ b/src/Artemis.UI/Screens/Debugger/Tabs/Performance/PerformanceDebugProfilerView.axaml @@ -9,7 +9,6 @@ +public partial class PerformanceDebugView : ReactiveUserControl { public PerformanceDebugView() { InitializeComponent(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Debugger/Tabs/Render/RenderDebugView.axaml.cs b/src/Artemis.UI/Screens/Debugger/Tabs/Render/RenderDebugView.axaml.cs index 0029dbaa5..4826cf124 100644 --- a/src/Artemis.UI/Screens/Debugger/Tabs/Render/RenderDebugView.axaml.cs +++ b/src/Artemis.UI/Screens/Debugger/Tabs/Render/RenderDebugView.axaml.cs @@ -3,15 +3,11 @@ using Avalonia.ReactiveUI; namespace Artemis.UI.Screens.Debugger.Render; -public class RenderDebugView : ReactiveUserControl +public partial class RenderDebugView : ReactiveUserControl { public RenderDebugView() { InitializeComponent(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Debugger/Tabs/Settings/DebugSettingsView.axaml.cs b/src/Artemis.UI/Screens/Debugger/Tabs/Settings/DebugSettingsView.axaml.cs index c146008aa..f0ba0577a 100644 --- a/src/Artemis.UI/Screens/Debugger/Tabs/Settings/DebugSettingsView.axaml.cs +++ b/src/Artemis.UI/Screens/Debugger/Tabs/Settings/DebugSettingsView.axaml.cs @@ -3,15 +3,11 @@ using Avalonia.ReactiveUI; namespace Artemis.UI.Screens.Debugger.Settings; -public class DebugSettingsView : ReactiveUserControl +public partial class DebugSettingsView : ReactiveUserControl { public DebugSettingsView() { InitializeComponent(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Device/DeviceDetectInputView.axaml.cs b/src/Artemis.UI/Screens/Device/DeviceDetectInputView.axaml.cs index 680126890..5dfd448c8 100644 --- a/src/Artemis.UI/Screens/Device/DeviceDetectInputView.axaml.cs +++ b/src/Artemis.UI/Screens/Device/DeviceDetectInputView.axaml.cs @@ -3,15 +3,11 @@ using Avalonia.ReactiveUI; namespace Artemis.UI.Screens.Device; -public class DeviceDetectInputView : ReactiveUserControl +public partial class DeviceDetectInputView : ReactiveUserControl { public DeviceDetectInputView() { InitializeComponent(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Device/DevicePropertiesView.axaml b/src/Artemis.UI/Screens/Device/DevicePropertiesView.axaml index 4cc1f6a55..e883d00a6 100644 --- a/src/Artemis.UI/Screens/Device/DevicePropertiesView.axaml +++ b/src/Artemis.UI/Screens/Device/DevicePropertiesView.axaml @@ -1,10 +1,10 @@ - - + - + @@ -71,5 +71,4 @@ - - \ No newline at end of file + \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Device/DevicePropertiesView.axaml.cs b/src/Artemis.UI/Screens/Device/DevicePropertiesView.axaml.cs index a67e142e5..14e491652 100644 --- a/src/Artemis.UI/Screens/Device/DevicePropertiesView.axaml.cs +++ b/src/Artemis.UI/Screens/Device/DevicePropertiesView.axaml.cs @@ -7,7 +7,7 @@ using Avalonia.Markup.Xaml; namespace Artemis.UI.Screens.Device; -public class DevicePropertiesView : ReactiveCoreWindow +public partial class DevicePropertiesView : ReactiveAppWindow { public DevicePropertiesView() { @@ -17,10 +17,6 @@ public class DevicePropertiesView : ReactiveCoreWindow - - + + @@ -50,8 +50,8 @@ - - + + diff --git a/src/Artemis.UI/Screens/Device/DeviceSettingsView.axaml.cs b/src/Artemis.UI/Screens/Device/DeviceSettingsView.axaml.cs index 50881c918..bc9c25196 100644 --- a/src/Artemis.UI/Screens/Device/DeviceSettingsView.axaml.cs +++ b/src/Artemis.UI/Screens/Device/DeviceSettingsView.axaml.cs @@ -3,15 +3,11 @@ using Avalonia.ReactiveUI; namespace Artemis.UI.Screens.Device; -public class DeviceSettingsView : ReactiveUserControl +public partial class DeviceSettingsView : ReactiveUserControl { public DeviceSettingsView() { InitializeComponent(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Device/Tabs/DeviceInfoTabView.axaml b/src/Artemis.UI/Screens/Device/Tabs/DeviceInfoTabView.axaml index 7d62cb3dc..a1daaad28 100644 --- a/src/Artemis.UI/Screens/Device/Tabs/DeviceInfoTabView.axaml +++ b/src/Artemis.UI/Screens/Device/Tabs/DeviceInfoTabView.axaml @@ -12,16 +12,16 @@ Device name - + Manufacturer - + Device type - + Physical layout @@ -34,15 +34,15 @@ Size (1px = 1mm) - + Location (1px = 1mm) - + Rotation (degrees) - + Logical layout @@ -67,7 +67,7 @@ - + Image file path diff --git a/src/Artemis.UI/Screens/Device/Tabs/DeviceInfoTabView.axaml.cs b/src/Artemis.UI/Screens/Device/Tabs/DeviceInfoTabView.axaml.cs index ce1b36821..4c5516ee3 100644 --- a/src/Artemis.UI/Screens/Device/Tabs/DeviceInfoTabView.axaml.cs +++ b/src/Artemis.UI/Screens/Device/Tabs/DeviceInfoTabView.axaml.cs @@ -3,15 +3,11 @@ using Avalonia.ReactiveUI; namespace Artemis.UI.Screens.Device; -public class DeviceInfoTabView : ReactiveUserControl +public partial class DeviceInfoTabView : ReactiveUserControl { public DeviceInfoTabView() { InitializeComponent(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Device/Tabs/DeviceLedsTabView.axaml.cs b/src/Artemis.UI/Screens/Device/Tabs/DeviceLedsTabView.axaml.cs index 540f47f26..263abb0ce 100644 --- a/src/Artemis.UI/Screens/Device/Tabs/DeviceLedsTabView.axaml.cs +++ b/src/Artemis.UI/Screens/Device/Tabs/DeviceLedsTabView.axaml.cs @@ -3,15 +3,11 @@ using Avalonia.ReactiveUI; namespace Artemis.UI.Screens.Device; -public class DeviceLedsTabView : ReactiveUserControl +public partial class DeviceLedsTabView : ReactiveUserControl { public DeviceLedsTabView() { InitializeComponent(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Device/Tabs/DeviceLogicalLayoutDialogView.axaml.cs b/src/Artemis.UI/Screens/Device/Tabs/DeviceLogicalLayoutDialogView.axaml.cs index 6a7374f55..c90b51c67 100644 --- a/src/Artemis.UI/Screens/Device/Tabs/DeviceLogicalLayoutDialogView.axaml.cs +++ b/src/Artemis.UI/Screens/Device/Tabs/DeviceLogicalLayoutDialogView.axaml.cs @@ -8,17 +8,15 @@ using Avalonia.Threading; namespace Artemis.UI.Screens.Device; -public class DeviceLogicalLayoutDialogView : ReactiveUserControl +public partial class DeviceLogicalLayoutDialogView : ReactiveUserControl { private readonly AutoCompleteBox _autoCompleteBox; public DeviceLogicalLayoutDialogView() { InitializeComponent(); - - _autoCompleteBox = this.Get("RegionsAutoCompleteBox"); - _autoCompleteBox.ItemFilter += SearchRegions; - + + RegionsAutoCompleteBox.ItemFilter += SearchRegions; Dispatcher.UIThread.InvokeAsync(DelayedAutoFocus); } @@ -39,8 +37,4 @@ public class DeviceLogicalLayoutDialogView : ReactiveUserControl +public partial class DevicePhysicalLayoutDialogView : ReactiveUserControl { public DevicePhysicalLayoutDialogView() { InitializeComponent(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Device/Tabs/DevicePropertiesTabView.axaml.cs b/src/Artemis.UI/Screens/Device/Tabs/DevicePropertiesTabView.axaml.cs index 44cb3cf46..f71b14155 100644 --- a/src/Artemis.UI/Screens/Device/Tabs/DevicePropertiesTabView.axaml.cs +++ b/src/Artemis.UI/Screens/Device/Tabs/DevicePropertiesTabView.axaml.cs @@ -4,17 +4,13 @@ using Avalonia.ReactiveUI; namespace Artemis.UI.Screens.Device; -public class DevicePropertiesTabView : ReactiveUserControl +public partial class DevicePropertiesTabView : ReactiveUserControl { public DevicePropertiesTabView() { InitializeComponent(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } private void InputElement_OnPointerReleased(object? sender, PointerReleasedEventArgs e) { diff --git a/src/Artemis.UI/Screens/Device/Tabs/InputMappingsTabView.axaml.cs b/src/Artemis.UI/Screens/Device/Tabs/InputMappingsTabView.axaml.cs index da7275845..c5a533ade 100644 --- a/src/Artemis.UI/Screens/Device/Tabs/InputMappingsTabView.axaml.cs +++ b/src/Artemis.UI/Screens/Device/Tabs/InputMappingsTabView.axaml.cs @@ -3,15 +3,11 @@ using Avalonia.ReactiveUI; namespace Artemis.UI.Screens.Device; -public class InputMappingsTabView : ReactiveUserControl +public partial class InputMappingsTabView : ReactiveUserControl { public InputMappingsTabView() { InitializeComponent(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Home/HomeView.axaml b/src/Artemis.UI/Screens/Home/HomeView.axaml index 691770a13..d6b0bbe35 100644 --- a/src/Artemis.UI/Screens/Home/HomeView.axaml +++ b/src/Artemis.UI/Screens/Home/HomeView.axaml @@ -117,7 +117,7 @@ Feel like making a donation? It would be gratefully received. Click the button to donate via PayPal. diff --git a/src/Artemis.UI/Screens/Home/HomeView.axaml.cs b/src/Artemis.UI/Screens/Home/HomeView.axaml.cs index 43f3bf653..881d46848 100644 --- a/src/Artemis.UI/Screens/Home/HomeView.axaml.cs +++ b/src/Artemis.UI/Screens/Home/HomeView.axaml.cs @@ -3,15 +3,11 @@ using Avalonia.ReactiveUI; namespace Artemis.UI.Screens.Home; -public class HomeView : ReactiveUserControl +public partial class HomeView : ReactiveUserControl { public HomeView() { InitializeComponent(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Plugins/Dialogs/PluginPrerequisitesInstallDialogView.axaml.cs b/src/Artemis.UI/Screens/Plugins/Dialogs/PluginPrerequisitesInstallDialogView.axaml.cs index b46a9cd9d..5186027b4 100644 --- a/src/Artemis.UI/Screens/Plugins/Dialogs/PluginPrerequisitesInstallDialogView.axaml.cs +++ b/src/Artemis.UI/Screens/Plugins/Dialogs/PluginPrerequisitesInstallDialogView.axaml.cs @@ -3,15 +3,11 @@ using Avalonia.ReactiveUI; namespace Artemis.UI.Screens.Plugins; -public class PluginPrerequisitesInstallDialogView : ReactiveUserControl +public partial class PluginPrerequisitesInstallDialogView : ReactiveUserControl { public PluginPrerequisitesInstallDialogView() { InitializeComponent(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Plugins/Dialogs/PluginPrerequisitesInstallDialogViewModel.cs b/src/Artemis.UI/Screens/Plugins/Dialogs/PluginPrerequisitesInstallDialogViewModel.cs index b2a698040..a8de70fbd 100644 --- a/src/Artemis.UI/Screens/Plugins/Dialogs/PluginPrerequisitesInstallDialogViewModel.cs +++ b/src/Artemis.UI/Screens/Plugins/Dialogs/PluginPrerequisitesInstallDialogViewModel.cs @@ -11,6 +11,7 @@ using Artemis.UI.DryIoc.Factories; using Artemis.UI.Shared; using Artemis.UI.Shared.Services; using Avalonia.Threading; +using FluentAvalonia.Core; using FluentAvalonia.UI.Controls; using ReactiveUI; using ContentDialogButton = Artemis.UI.Shared.Services.Builders.ContentDialogButton; @@ -98,7 +99,7 @@ public class PluginPrerequisitesInstallDialogViewModel : ContentDialogViewModelB private async Task ExecuteInstall() { - ContentDialogClosingDeferral? deferral = null; + Deferral? deferral = null; if (ContentDialog != null) ContentDialog.Closing += (_, args) => deferral = args.GetDeferral(); diff --git a/src/Artemis.UI/Screens/Plugins/Dialogs/PluginPrerequisitesUninstallDialogView.axaml.cs b/src/Artemis.UI/Screens/Plugins/Dialogs/PluginPrerequisitesUninstallDialogView.axaml.cs index ee9196f83..6ea72f1da 100644 --- a/src/Artemis.UI/Screens/Plugins/Dialogs/PluginPrerequisitesUninstallDialogView.axaml.cs +++ b/src/Artemis.UI/Screens/Plugins/Dialogs/PluginPrerequisitesUninstallDialogView.axaml.cs @@ -3,15 +3,11 @@ using Avalonia.ReactiveUI; namespace Artemis.UI.Screens.Plugins; -public class PluginPrerequisitesUninstallDialogView : ReactiveUserControl +public partial class PluginPrerequisitesUninstallDialogView : ReactiveUserControl { public PluginPrerequisitesUninstallDialogView() { InitializeComponent(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Plugins/Dialogs/PluginPrerequisitesUninstallDialogViewModel.cs b/src/Artemis.UI/Screens/Plugins/Dialogs/PluginPrerequisitesUninstallDialogViewModel.cs index 5bbd3e44d..b65e72d23 100644 --- a/src/Artemis.UI/Screens/Plugins/Dialogs/PluginPrerequisitesUninstallDialogViewModel.cs +++ b/src/Artemis.UI/Screens/Plugins/Dialogs/PluginPrerequisitesUninstallDialogViewModel.cs @@ -12,6 +12,7 @@ using Artemis.UI.DryIoc.Factories; using Artemis.UI.Shared; using Artemis.UI.Shared.Services; using Avalonia.Threading; +using FluentAvalonia.Core; using FluentAvalonia.UI.Controls; using ReactiveUI; using ContentDialogButton = Artemis.UI.Shared.Services.Builders.ContentDialogButton; @@ -83,7 +84,7 @@ public class PluginPrerequisitesUninstallDialogViewModel : ContentDialogViewMode private async Task ExecuteUninstall() { - ContentDialogClosingDeferral? deferral = null; + Deferral? deferral = null; if (ContentDialog != null) ContentDialog.Closing += (_, args) => deferral = args.GetDeferral(); diff --git a/src/Artemis.UI/Screens/Plugins/PluginFeatureView.axaml.cs b/src/Artemis.UI/Screens/Plugins/PluginFeatureView.axaml.cs index 3b8f761eb..7f21c9ce0 100644 --- a/src/Artemis.UI/Screens/Plugins/PluginFeatureView.axaml.cs +++ b/src/Artemis.UI/Screens/Plugins/PluginFeatureView.axaml.cs @@ -3,15 +3,11 @@ using Avalonia.ReactiveUI; namespace Artemis.UI.Screens.Plugins; -public class PluginFeatureView : ReactiveUserControl +public partial class PluginFeatureView : ReactiveUserControl { public PluginFeatureView() { InitializeComponent(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Plugins/PluginPlatformView.axaml.cs b/src/Artemis.UI/Screens/Plugins/PluginPlatformView.axaml.cs index 20e155f36..2d858d732 100644 --- a/src/Artemis.UI/Screens/Plugins/PluginPlatformView.axaml.cs +++ b/src/Artemis.UI/Screens/Plugins/PluginPlatformView.axaml.cs @@ -3,15 +3,11 @@ using Avalonia.Markup.Xaml; namespace Artemis.UI.Screens.Plugins; -public class PluginPlatformView : UserControl +public partial class PluginPlatformView : UserControl { public PluginPlatformView() { InitializeComponent(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Plugins/PluginPrerequisiteActionView.axaml.cs b/src/Artemis.UI/Screens/Plugins/PluginPrerequisiteActionView.axaml.cs index e8a86a27e..3e58859af 100644 --- a/src/Artemis.UI/Screens/Plugins/PluginPrerequisiteActionView.axaml.cs +++ b/src/Artemis.UI/Screens/Plugins/PluginPrerequisiteActionView.axaml.cs @@ -3,15 +3,11 @@ using Avalonia.Markup.Xaml; namespace Artemis.UI.Screens.Plugins; -public class PluginPrerequisiteActionView : UserControl +public partial class PluginPrerequisiteActionView : UserControl { public PluginPrerequisiteActionView() { InitializeComponent(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Plugins/PluginPrerequisiteView.axaml b/src/Artemis.UI/Screens/Plugins/PluginPrerequisiteView.axaml index 54996af62..af5ac19bf 100644 --- a/src/Artemis.UI/Screens/Plugins/PluginPrerequisiteView.axaml +++ b/src/Artemis.UI/Screens/Plugins/PluginPrerequisiteView.axaml @@ -18,7 +18,7 @@ - + diff --git a/src/Artemis.UI/Screens/Plugins/PluginPrerequisiteView.axaml.cs b/src/Artemis.UI/Screens/Plugins/PluginPrerequisiteView.axaml.cs index 3ba622127..50cbd2c39 100644 --- a/src/Artemis.UI/Screens/Plugins/PluginPrerequisiteView.axaml.cs +++ b/src/Artemis.UI/Screens/Plugins/PluginPrerequisiteView.axaml.cs @@ -3,15 +3,11 @@ using Avalonia.ReactiveUI; namespace Artemis.UI.Screens.Plugins; -public class PluginPrerequisiteView : ReactiveUserControl +public partial class PluginPrerequisiteView : ReactiveUserControl { public PluginPrerequisiteView() { InitializeComponent(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Plugins/PluginSettingsView.axaml.cs b/src/Artemis.UI/Screens/Plugins/PluginSettingsView.axaml.cs index 7f0608689..52179210f 100644 --- a/src/Artemis.UI/Screens/Plugins/PluginSettingsView.axaml.cs +++ b/src/Artemis.UI/Screens/Plugins/PluginSettingsView.axaml.cs @@ -3,15 +3,11 @@ using Avalonia.ReactiveUI; namespace Artemis.UI.Screens.Plugins; -public class PluginSettingsView : ReactiveUserControl +public partial class PluginSettingsView : ReactiveUserControl { public PluginSettingsView() { InitializeComponent(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Plugins/PluginSettingsWindowView.axaml b/src/Artemis.UI/Screens/Plugins/PluginSettingsWindowView.axaml index f653027b5..12dd5b763 100644 --- a/src/Artemis.UI/Screens/Plugins/PluginSettingsWindowView.axaml +++ b/src/Artemis.UI/Screens/Plugins/PluginSettingsWindowView.axaml @@ -1,17 +1,17 @@ - - + + - - - + + + \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Plugins/PluginSettingsWindowView.axaml.cs b/src/Artemis.UI/Screens/Plugins/PluginSettingsWindowView.axaml.cs index 0ab658d66..41920c857 100644 --- a/src/Artemis.UI/Screens/Plugins/PluginSettingsWindowView.axaml.cs +++ b/src/Artemis.UI/Screens/Plugins/PluginSettingsWindowView.axaml.cs @@ -8,7 +8,7 @@ using ReactiveUI; namespace Artemis.UI.Screens.Plugins; -public class PluginSettingsWindowView : ReactiveCoreWindow +public partial class PluginSettingsWindowView : ReactiveAppWindow { public PluginSettingsWindowView() { @@ -29,8 +29,4 @@ public class PluginSettingsWindowView : ReactiveCoreWindow - - + + @@ -81,8 +81,8 @@ - - + + +public partial class PluginView : ReactiveUserControl { - private readonly CheckBox _enabledToggle; - public PluginView() { InitializeComponent(); - _enabledToggle = this.Find("EnabledToggle"); - _enabledToggle.Click += EnabledToggleOnClick; + EnabledToggle.Click += EnabledToggleOnClick; } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } private void EnabledToggleOnClick(object? sender, RoutedEventArgs e) { diff --git a/src/Artemis.UI/Screens/Plugins/PluginViewModel.cs b/src/Artemis.UI/Screens/Plugins/PluginViewModel.cs index 24102dc8c..35d37aa0e 100644 --- a/src/Artemis.UI/Screens/Plugins/PluginViewModel.cs +++ b/src/Artemis.UI/Screens/Plugins/PluginViewModel.cs @@ -13,7 +13,6 @@ using Artemis.UI.Shared.Services; using Artemis.UI.Shared.Services.Builders; using Avalonia.Controls; using Avalonia.Threading; -using DryIoc; using Material.Icons; using ReactiveUI; diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/DisplayCondition/ConditionTypes/AlwaysOnConditionView.axaml.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/DisplayCondition/ConditionTypes/AlwaysOnConditionView.axaml.cs index 99520854f..20c9a7452 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/DisplayCondition/ConditionTypes/AlwaysOnConditionView.axaml.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/DisplayCondition/ConditionTypes/AlwaysOnConditionView.axaml.cs @@ -3,15 +3,11 @@ using Avalonia.Markup.Xaml; namespace Artemis.UI.Screens.ProfileEditor.DisplayCondition.ConditionTypes; -public class AlwaysOnConditionView : UserControl +public partial class AlwaysOnConditionView : UserControl { public AlwaysOnConditionView() { InitializeComponent(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/DisplayCondition/ConditionTypes/EventConditionView.axaml.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/DisplayCondition/ConditionTypes/EventConditionView.axaml.cs index b9bfdfd71..2240a63ea 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/DisplayCondition/ConditionTypes/EventConditionView.axaml.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/DisplayCondition/ConditionTypes/EventConditionView.axaml.cs @@ -3,15 +3,11 @@ using Avalonia.ReactiveUI; namespace Artemis.UI.Screens.ProfileEditor.DisplayCondition.ConditionTypes; -public class EventConditionView : ReactiveUserControl +public partial class EventConditionView : ReactiveUserControl { public EventConditionView() { InitializeComponent(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/DisplayCondition/ConditionTypes/EventConditionViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/DisplayCondition/ConditionTypes/EventConditionViewModel.cs index 7333571c8..fbd8eea25 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/DisplayCondition/ConditionTypes/EventConditionViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/DisplayCondition/ConditionTypes/EventConditionViewModel.cs @@ -1,4 +1,5 @@ using System.Reactive; +using System.Reactive.Disposables; using System.Reactive.Linq; using System.Threading.Tasks; using Artemis.Core; @@ -8,7 +9,6 @@ using Artemis.UI.Shared; using Artemis.UI.Shared.Services; using Artemis.UI.Shared.Services.ProfileEditor; using Artemis.UI.Shared.Services.ProfileEditor.Commands; -using Avalonia.Controls.Mixins; using ReactiveUI; namespace Artemis.UI.Screens.ProfileEditor.DisplayCondition.ConditionTypes; diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/DisplayCondition/ConditionTypes/PlayOnceConditionView.axaml.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/DisplayCondition/ConditionTypes/PlayOnceConditionView.axaml.cs index 39b606054..068dfeca2 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/DisplayCondition/ConditionTypes/PlayOnceConditionView.axaml.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/DisplayCondition/ConditionTypes/PlayOnceConditionView.axaml.cs @@ -3,15 +3,11 @@ using Avalonia.Markup.Xaml; namespace Artemis.UI.Screens.ProfileEditor.DisplayCondition.ConditionTypes; -public class PlayOnceConditionView : UserControl +public partial class PlayOnceConditionView : UserControl { public PlayOnceConditionView() { InitializeComponent(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/DisplayCondition/ConditionTypes/StaticConditionView.axaml.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/DisplayCondition/ConditionTypes/StaticConditionView.axaml.cs index 83855685c..cbe8b1ab1 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/DisplayCondition/ConditionTypes/StaticConditionView.axaml.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/DisplayCondition/ConditionTypes/StaticConditionView.axaml.cs @@ -3,15 +3,11 @@ using Avalonia.ReactiveUI; namespace Artemis.UI.Screens.ProfileEditor.DisplayCondition.ConditionTypes; -public class StaticConditionView : ReactiveUserControl +public partial class StaticConditionView : ReactiveUserControl { public StaticConditionView() { InitializeComponent(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/DisplayCondition/DisplayConditionScriptView.axaml.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/DisplayCondition/DisplayConditionScriptView.axaml.cs index 730ad046a..95484f28d 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/DisplayCondition/DisplayConditionScriptView.axaml.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/DisplayCondition/DisplayConditionScriptView.axaml.cs @@ -3,15 +3,11 @@ using Avalonia.ReactiveUI; namespace Artemis.UI.Screens.ProfileEditor.DisplayCondition; -public class DisplayConditionScriptView : ReactiveUserControl +public partial class DisplayConditionScriptView : ReactiveUserControl { public DisplayConditionScriptView() { InitializeComponent(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/DisplayCondition/DisplayConditionScriptViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/DisplayCondition/DisplayConditionScriptViewModel.cs index 87b0a3104..edc771a93 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/DisplayCondition/DisplayConditionScriptViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/DisplayCondition/DisplayConditionScriptViewModel.cs @@ -1,12 +1,12 @@ using System.Collections.ObjectModel; using System.Linq; +using System.Reactive.Disposables; using System.Reactive.Linq; using Artemis.Core; using Artemis.UI.DryIoc.Factories; using Artemis.UI.Shared; using Artemis.UI.Shared.Services.ProfileEditor; using Artemis.UI.Shared.Services.ProfileEditor.Commands; -using Avalonia.Controls.Mixins; using ReactiveUI; namespace Artemis.UI.Screens.ProfileEditor.DisplayCondition; diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/MenuBar/MenuBarView.axaml.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/MenuBar/MenuBarView.axaml.cs index eedb4560a..2049889ad 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/MenuBar/MenuBarView.axaml.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/MenuBar/MenuBarView.axaml.cs @@ -6,17 +6,13 @@ using Avalonia.VisualTree; namespace Artemis.UI.Screens.ProfileEditor.MenuBar; -public class MenuBarView : ReactiveUserControl +public partial class MenuBarView : ReactiveUserControl { public MenuBarView() { InitializeComponent(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } private void MenuBase_OnMenuClosed(object? sender, RoutedEventArgs e) { diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/Playback/PlaybackView.axaml.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/Playback/PlaybackView.axaml.cs index d94c76117..06a684191 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/Playback/PlaybackView.axaml.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/Playback/PlaybackView.axaml.cs @@ -3,15 +3,11 @@ using Avalonia.ReactiveUI; namespace Artemis.UI.Screens.ProfileEditor.Playback; -public class PlaybackView : ReactiveUserControl +public partial class PlaybackView : ReactiveUserControl { public PlaybackView() { InitializeComponent(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/Behaviors/ProfileTreeViewDropHandler.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/Behaviors/ProfileTreeViewDropHandler.cs index 79c456926..0a7ba090f 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/Behaviors/ProfileTreeViewDropHandler.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/Behaviors/ProfileTreeViewDropHandler.cs @@ -3,7 +3,6 @@ using System.Collections.ObjectModel; using System.Linq; using Avalonia; using Avalonia.Controls; -using Avalonia.Controls.Generators; using Avalonia.Input; using Avalonia.Interactivity; using Avalonia.VisualTree; @@ -15,7 +14,7 @@ public class ProfileTreeViewDropHandler : DropHandlerBase { public override bool Validate(object? sender, DragEventArgs e, object? sourceContext, object? targetContext, object? state) { - if (e.Source is IControl && sender is TreeView treeView) + if (e.Source is Control && sender is TreeView treeView) return Validate(treeView, e, sourceContext, targetContext, false); return false; @@ -24,7 +23,7 @@ public class ProfileTreeViewDropHandler : DropHandlerBase public override bool Execute(object? sender, DragEventArgs e, object? sourceContext, object? targetContext, object? state) { bool result = false; - if (e.Source is IControl && sender is TreeView treeView) + if (e.Source is Control && sender is TreeView treeView) result = Validate(treeView, e, sourceContext, targetContext, true); if (sender is ItemsControl itemsControl) @@ -46,8 +45,8 @@ public class ProfileTreeViewDropHandler : DropHandlerBase private bool Validate(TreeView treeView, DragEventArgs e, object? sourceContext, object? targetContext, bool bExecute) where T : TreeItemViewModel { Point position = e.GetPosition(treeView); - IVisual? targetVisual = treeView.GetVisualAt(position).FindAncestorOfType(); - if (sourceContext is not T sourceNode || targetContext is not ProfileTreeViewModel vm || targetVisual is not IControl {DataContext: T targetNode}) + TreeViewItem? targetVisual = treeView.GetVisualAt(position).FindAncestorOfType(); + if (sourceContext is not T sourceNode || targetContext is not ProfileTreeViewModel vm || targetVisual is not Control {DataContext: T targetNode}) return false; if (bExecute && targetNode == sourceNode) return false; @@ -69,7 +68,7 @@ public class ProfileTreeViewDropHandler : DropHandlerBase } else { - IVisual? header = targetVisual.GetVisualDescendants().FirstOrDefault(d => d is Border b && b.Name == "PART_LayoutRoot"); + Visual? header = targetVisual.GetVisualDescendants().FirstOrDefault(d => d is Border b && b.Name == "PART_LayoutRoot"); if (header != null) { position = e.GetPosition(header); @@ -119,7 +118,7 @@ public class ProfileTreeViewDropHandler : DropHandlerBase } else { - SetDraggingPseudoClasses((IControl) targetVisual, dropType); + SetDraggingPseudoClasses(targetVisual, dropType); } return true; @@ -129,12 +128,12 @@ public class ProfileTreeViewDropHandler : DropHandlerBase { List result = new(); - foreach (ItemContainerInfo containerInfo in currentNode.ItemContainerGenerator.Containers) + foreach (Control containerControl in currentNode.GetRealizedContainers()) { - if (containerInfo.ContainerControl is TreeViewItem treeViewItem && containerInfo.Item is TreeItemViewModel) + if (containerControl is TreeViewItem treeViewItem && containerControl.DataContext is TreeItemViewModel) { result.Add(treeViewItem); - if (treeViewItem.ItemContainerGenerator.Containers.Any()) + if (treeViewItem.ItemCount > 0) result.AddRange(GetFlattenedTreeView(treeViewItem)); } } @@ -142,7 +141,7 @@ public class ProfileTreeViewDropHandler : DropHandlerBase return result; } - private void SetDraggingPseudoClasses(IControl control, TreeDropType type) + private void SetDraggingPseudoClasses(TreeViewItem control, TreeDropType type) { if (type == TreeDropType.None) { diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/Dialogs/AdaptionHints/CategoryAdaptionHintView.axaml.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/Dialogs/AdaptionHints/CategoryAdaptionHintView.axaml.cs index 884346e0b..68e0563e8 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/Dialogs/AdaptionHints/CategoryAdaptionHintView.axaml.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/Dialogs/AdaptionHints/CategoryAdaptionHintView.axaml.cs @@ -3,15 +3,11 @@ using Avalonia.Markup.Xaml; namespace Artemis.UI.Screens.ProfileEditor.ProfileTree.Dialogs.AdaptionHints; -public class CategoryAdaptionHintView : UserControl +public partial class CategoryAdaptionHintView : UserControl { public CategoryAdaptionHintView() { InitializeComponent(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/Dialogs/AdaptionHints/DeviceAdaptionHintView.axaml.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/Dialogs/AdaptionHints/DeviceAdaptionHintView.axaml.cs index f2ec263d3..bc64fa3e6 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/Dialogs/AdaptionHints/DeviceAdaptionHintView.axaml.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/Dialogs/AdaptionHints/DeviceAdaptionHintView.axaml.cs @@ -3,15 +3,11 @@ using Avalonia.Markup.Xaml; namespace Artemis.UI.Screens.ProfileEditor.ProfileTree.Dialogs.AdaptionHints; -public class DeviceAdaptionHintView : UserControl +public partial class DeviceAdaptionHintView : UserControl { public DeviceAdaptionHintView() { InitializeComponent(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/Dialogs/AdaptionHints/KeyboardSectionAdaptionHintView.axaml.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/Dialogs/AdaptionHints/KeyboardSectionAdaptionHintView.axaml.cs index 1fcb02a6d..df0eb98f7 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/Dialogs/AdaptionHints/KeyboardSectionAdaptionHintView.axaml.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/Dialogs/AdaptionHints/KeyboardSectionAdaptionHintView.axaml.cs @@ -3,15 +3,11 @@ using Avalonia.Markup.Xaml; namespace Artemis.UI.Screens.ProfileEditor.ProfileTree.Dialogs.AdaptionHints; -public class KeyboardSectionAdaptionHintView : UserControl +public partial class KeyboardSectionAdaptionHintView : UserControl { public KeyboardSectionAdaptionHintView() { InitializeComponent(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/Dialogs/LayerHintsDialogView.axaml b/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/Dialogs/LayerHintsDialogView.axaml index 50afd41b8..1ff26bba4 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/Dialogs/LayerHintsDialogView.axaml +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/Dialogs/LayerHintsDialogView.axaml @@ -1,10 +1,11 @@ - - - + + @@ -87,12 +88,12 @@ - + Add hint - + - \ No newline at end of file + \ No newline at end of file diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/Dialogs/LayerHintsDialogView.axaml.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/Dialogs/LayerHintsDialogView.axaml.cs index 4bb0db390..c7703fe65 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/Dialogs/LayerHintsDialogView.axaml.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/Dialogs/LayerHintsDialogView.axaml.cs @@ -4,7 +4,7 @@ using Avalonia.Markup.Xaml; namespace Artemis.UI.Screens.ProfileEditor.ProfileTree.Dialogs; -public class LayerHintsDialogView : ReactiveCoreWindow +public partial class LayerHintsDialogView : ReactiveAppWindow { public LayerHintsDialogView() { @@ -14,8 +14,4 @@ public class LayerHintsDialogView : ReactiveCoreWindow +public partial class FolderTreeItemView : ReactiveUserControl { public FolderTreeItemView() { @@ -18,16 +17,12 @@ public class FolderTreeItemView : ReactiveUserControl { ViewModel?.Rename.Subscribe(_ => { - this.Get("Input").Focus(); - this.Get("Input").SelectAll(); + Input.Focus(); + Input.SelectAll(); }).DisposeWith(d); }); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } private void InputElement_OnKeyUp(object? sender, KeyEventArgs e) { diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/LayerTreeItemView.axaml.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/LayerTreeItemView.axaml.cs index e34cef5cb..831af0d5a 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/LayerTreeItemView.axaml.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/LayerTreeItemView.axaml.cs @@ -1,6 +1,5 @@ using System; using System.Reactive.Disposables; -using Avalonia.Controls; using Avalonia.Input; using Avalonia.Interactivity; using Avalonia.Markup.Xaml; @@ -9,7 +8,7 @@ using ReactiveUI; namespace Artemis.UI.Screens.ProfileEditor.ProfileTree; -public class LayerTreeItemView : ReactiveUserControl +public partial class LayerTreeItemView : ReactiveUserControl { public LayerTreeItemView() { @@ -18,16 +17,12 @@ public class LayerTreeItemView : ReactiveUserControl { ViewModel?.Rename.Subscribe(_ => { - this.Get("Input").Focus(); - this.Get("Input").SelectAll(); + Input.Focus(); + Input.SelectAll(); }).DisposeWith(d); }); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } private void InputElement_OnKeyUp(object? sender, KeyEventArgs e) { diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/ProfileTreeView.axaml b/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/ProfileTreeView.axaml index f2438acb5..286b33c93 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/ProfileTreeView.axaml +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/ProfileTreeView.axaml @@ -23,8 +23,8 @@ - - - - - - - diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/ProfileTreeView.axaml.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/ProfileTreeView.axaml.cs index d519466b3..c658362f3 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/ProfileTreeView.axaml.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/ProfileTreeView.axaml.cs @@ -13,9 +13,8 @@ using Avalonia.VisualTree; namespace Artemis.UI.Screens.ProfileEditor.ProfileTree; -public class ProfileTreeView : ReactiveUserControl +public partial class ProfileTreeView : ReactiveUserControl { - private readonly TreeView _treeView; private Image? _dragAdorner; private Point _dragStartPosition; private Point _elementDragOffset; @@ -23,11 +22,10 @@ public class ProfileTreeView : ReactiveUserControl public ProfileTreeView() { InitializeComponent(); - _treeView = this.Get("ProfileTreeView"); AddHandler(DragDrop.DragEnterEvent, HandleDragEnterEvent, RoutingStrategies.Direct | RoutingStrategies.Tunnel | RoutingStrategies.Bubble, true); AddHandler(DragDrop.DragOverEvent, HandleDragOver, RoutingStrategies.Direct | RoutingStrategies.Tunnel | RoutingStrategies.Bubble, true); - AddHandler(PointerEnterEvent, HandlePointerEnter, RoutingStrategies.Direct | RoutingStrategies.Tunnel | RoutingStrategies.Bubble, true); + AddHandler(PointerEnteredEvent, HandlePointerEnter, RoutingStrategies.Direct | RoutingStrategies.Tunnel | RoutingStrategies.Bubble, true); } private void HandlePointerEnter(object? sender, PointerEventArgs e) @@ -115,13 +113,9 @@ public class ProfileTreeView : ReactiveUserControl _dragAdorner.RenderTransform = new TranslateTransform(_dragStartPosition.X - _elementDragOffset.X, position.Y - _elementDragOffset.Y); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } private void ProfileTreeView_OnSelectionChanged(object? sender, SelectionChangedEventArgs e) { - _treeView.Focus(); + Profile.Focus(); } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/DataBinding/DataBindingView.axaml.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/DataBinding/DataBindingView.axaml.cs index d38d4272f..f0d5a3e71 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/DataBinding/DataBindingView.axaml.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/DataBinding/DataBindingView.axaml.cs @@ -3,15 +3,11 @@ using Avalonia.ReactiveUI; namespace Artemis.UI.Screens.ProfileEditor.Properties.DataBinding; -public class DataBindingView : ReactiveUserControl +public partial class DataBindingView : ReactiveUserControl { public DataBindingView() { InitializeComponent(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Dialogs/AddEffectView.axaml.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Dialogs/AddEffectView.axaml.cs index 77b18f314..89a8aab4c 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Dialogs/AddEffectView.axaml.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Dialogs/AddEffectView.axaml.cs @@ -6,17 +6,13 @@ using Avalonia.ReactiveUI; namespace Artemis.UI.Screens.ProfileEditor.Properties.Dialogs; -public class AddEffectView : ReactiveUserControl +public partial class AddEffectView : ReactiveUserControl { public AddEffectView() { InitializeComponent(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } private void InputElement_OnPointerReleased(object? sender, PointerReleasedEventArgs e) { diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Dialogs/TimelineSegmentEditView.axaml.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Dialogs/TimelineSegmentEditView.axaml.cs index fb0f6d893..aa499ec9d 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Dialogs/TimelineSegmentEditView.axaml.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Dialogs/TimelineSegmentEditView.axaml.cs @@ -3,15 +3,11 @@ using Avalonia.ReactiveUI; namespace Artemis.UI.Screens.ProfileEditor.Properties.Dialogs; -public class TimelineSegmentEditView : ReactiveUserControl +public partial class TimelineSegmentEditView : ReactiveUserControl { public TimelineSegmentEditView() { InitializeComponent(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/PropertiesView.axaml.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/PropertiesView.axaml.cs index 602eb1424..beedfbbea 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/PropertiesView.axaml.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/PropertiesView.axaml.cs @@ -1,8 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; -using Avalonia.Controls; -using Avalonia.Controls.Shapes; +using Avalonia; using Avalonia.Input; using Avalonia.Markup.Xaml; using Avalonia.ReactiveUI; @@ -10,22 +9,13 @@ using Avalonia.VisualTree; namespace Artemis.UI.Screens.ProfileEditor.Properties; -public class PropertiesView : ReactiveUserControl +public partial class PropertiesView : ReactiveUserControl { - private readonly Polygon _timelineCaret; - private readonly Line _timelineLine; - public PropertiesView() { InitializeComponent(); - _timelineCaret = this.Get("TimelineCaret"); - _timelineLine = this.Get("TimelineLine"); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } private void ApplyTransition(bool enable) { @@ -58,12 +48,12 @@ public class PropertiesView : ReactiveUserControl if (!e.GetCurrentPoint(this).Properties.IsLeftButtonPressed || ViewModel == null) return; - IInputElement? senderElement = (IInputElement?) sender; + Visual? senderElement = (Visual?) sender; if (senderElement == null) return; // Get the parent grid, need that for our position - IVisual? parent = senderElement.VisualParent; + Visual? parent = senderElement.GetVisualParent(); double x = Math.Max(0, e.GetPosition(parent).X); TimeSpan newTime = TimeSpan.FromSeconds(x / ViewModel.PixelsPerSecond); newTime = RoundTime(newTime); @@ -84,11 +74,11 @@ public class PropertiesView : ReactiveUserControl private void TimelineHeader_OnPointerReleased(object? sender, PointerReleasedEventArgs e) { - if (ViewModel == null || sender is not IInputElement senderElement) + if (ViewModel == null || sender is not Visual senderElement) return; // Get the parent grid, need that for our position - double x = Math.Max(0, e.GetPosition(senderElement.VisualParent).X); + double x = Math.Max(0, e.GetPosition(senderElement.GetVisualParent()).X); TimeSpan newTime = TimeSpan.FromSeconds(x / ViewModel.PixelsPerSecond); ViewModel.TimelineViewModel.ChangeTime(RoundTime(newTime)); diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/Keyframes/TimelineEasingView.axaml.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/Keyframes/TimelineEasingView.axaml.cs index fa1d2f160..5aa75d59c 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/Keyframes/TimelineEasingView.axaml.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/Keyframes/TimelineEasingView.axaml.cs @@ -3,15 +3,11 @@ using Avalonia.Markup.Xaml; namespace Artemis.UI.Screens.ProfileEditor.Properties.Timeline.Keyframes; -public class TimelineEasingView : UserControl +public partial class TimelineEasingView : UserControl { public TimelineEasingView() { InitializeComponent(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/Keyframes/TimelineKeyframeView.axaml.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/Keyframes/TimelineKeyframeView.axaml.cs index ea1a6c5ff..cebade11d 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/Keyframes/TimelineKeyframeView.axaml.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/Keyframes/TimelineKeyframeView.axaml.cs @@ -6,7 +6,7 @@ using Avalonia.ReactiveUI; namespace Artemis.UI.Screens.ProfileEditor.Properties.Timeline.Keyframes; -public class TimelineKeyframeView : ReactiveUserControl +public partial class TimelineKeyframeView : ReactiveUserControl { private bool _moved; private TimelinePropertyView? _timelinePropertyView; @@ -30,10 +30,6 @@ public class TimelineKeyframeView : ReactiveUserControl +public partial class EndSegmentView : ReactiveUserControl { - private readonly Rectangle _keyframeDragAnchor; private double _dragOffset; public EndSegmentView() { InitializeComponent(); - _keyframeDragAnchor = this.Get("KeyframeDragAnchor"); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } private void KeyframeDragAnchor_OnPointerPressed(object? sender, PointerPressedEventArgs e) { if (ViewModel == null || !e.GetCurrentPoint(this).Properties.IsLeftButtonPressed) return; - e.Pointer.Capture(_keyframeDragAnchor); + e.Pointer.Capture(KeyframeDragAnchor); _dragOffset = ViewModel.Width - e.GetCurrentPoint(this).Position.X; ViewModel.StartResize(); @@ -34,14 +26,14 @@ public class EndSegmentView : ReactiveUserControl private void KeyframeDragAnchor_OnPointerMoved(object? sender, PointerEventArgs e) { - if (ViewModel == null || !ReferenceEquals(e.Pointer.Captured, _keyframeDragAnchor)) + if (ViewModel == null || !ReferenceEquals(e.Pointer.Captured, KeyframeDragAnchor)) return; ViewModel.UpdateResize(e.GetCurrentPoint(this).Position.X + _dragOffset, e.KeyModifiers.HasFlag(KeyModifiers.Shift), e.KeyModifiers.HasFlag(KeyModifiers.Control)); } private void KeyframeDragAnchor_OnPointerReleased(object? sender, PointerReleasedEventArgs e) { - if (ViewModel == null || !ReferenceEquals(e.Pointer.Captured, _keyframeDragAnchor)) + if (ViewModel == null || !ReferenceEquals(e.Pointer.Captured, KeyframeDragAnchor)) return; e.Pointer.Capture(null); ViewModel.FinishResize(e.GetCurrentPoint(this).Position.X + _dragOffset, e.KeyModifiers.HasFlag(KeyModifiers.Shift), e.KeyModifiers.HasFlag(KeyModifiers.Control)); diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/Segments/EndSegmentViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/Segments/EndSegmentViewModel.cs index 7e10e7999..1d556bb59 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/Segments/EndSegmentViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/Segments/EndSegmentViewModel.cs @@ -1,10 +1,10 @@ using System; +using System.Reactive.Disposables; using System.Reactive.Linq; using Artemis.Core; using Artemis.UI.Shared.Services; using Artemis.UI.Shared.Services.ProfileEditor; using Artemis.UI.Shared.Services.ProfileEditor.Commands; -using Avalonia.Controls.Mixins; using ReactiveUI; namespace Artemis.UI.Screens.ProfileEditor.Properties.Timeline.Segments; diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/Segments/MainSegmentView.axaml.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/Segments/MainSegmentView.axaml.cs index 8c09b98dc..4923e2def 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/Segments/MainSegmentView.axaml.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/Segments/MainSegmentView.axaml.cs @@ -1,32 +1,24 @@ -using Avalonia.Controls; -using Avalonia.Controls.Shapes; using Avalonia.Input; using Avalonia.Markup.Xaml; using Avalonia.ReactiveUI; namespace Artemis.UI.Screens.ProfileEditor.Properties.Timeline.Segments; -public class MainSegmentView : ReactiveUserControl +public partial class MainSegmentView : ReactiveUserControl { - private readonly Rectangle _keyframeDragAnchor; private double _dragOffset; public MainSegmentView() { InitializeComponent(); - _keyframeDragAnchor = this.Get("KeyframeDragAnchor"); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } private void KeyframeDragAnchor_OnPointerPressed(object? sender, PointerPressedEventArgs e) { if (ViewModel == null || !e.GetCurrentPoint(this).Properties.IsLeftButtonPressed) return; - e.Pointer.Capture(_keyframeDragAnchor); + e.Pointer.Capture(KeyframeDragAnchor); _dragOffset = ViewModel.Width - e.GetCurrentPoint(this).Position.X; ViewModel.StartResize(); @@ -34,14 +26,14 @@ public class MainSegmentView : ReactiveUserControl private void KeyframeDragAnchor_OnPointerMoved(object? sender, PointerEventArgs e) { - if (ViewModel == null || !ReferenceEquals(e.Pointer.Captured, _keyframeDragAnchor)) + if (ViewModel == null || !ReferenceEquals(e.Pointer.Captured, KeyframeDragAnchor)) return; ViewModel.UpdateResize(e.GetCurrentPoint(this).Position.X + _dragOffset, e.KeyModifiers.HasFlag(KeyModifiers.Shift), e.KeyModifiers.HasFlag(KeyModifiers.Control)); } private void KeyframeDragAnchor_OnPointerReleased(object? sender, PointerReleasedEventArgs e) { - if (ViewModel == null || !ReferenceEquals(e.Pointer.Captured, _keyframeDragAnchor)) + if (ViewModel == null || !ReferenceEquals(e.Pointer.Captured, KeyframeDragAnchor)) return; e.Pointer.Capture(null); ViewModel.FinishResize(e.GetCurrentPoint(this).Position.X + _dragOffset, e.KeyModifiers.HasFlag(KeyModifiers.Shift), e.KeyModifiers.HasFlag(KeyModifiers.Control)); diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/Segments/MainSegmentViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/Segments/MainSegmentViewModel.cs index 15ebb371c..a122bbb56 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/Segments/MainSegmentViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/Segments/MainSegmentViewModel.cs @@ -1,10 +1,10 @@ using System; +using System.Reactive.Disposables; using System.Reactive.Linq; using Artemis.Core; using Artemis.UI.Shared.Services; using Artemis.UI.Shared.Services.ProfileEditor; using Artemis.UI.Shared.Services.ProfileEditor.Commands; -using Avalonia.Controls.Mixins; using ReactiveUI; namespace Artemis.UI.Screens.ProfileEditor.Properties.Timeline.Segments; diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/Segments/StartSegmentView.axaml.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/Segments/StartSegmentView.axaml.cs index 9876e5c6c..231a80b51 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/Segments/StartSegmentView.axaml.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/Segments/StartSegmentView.axaml.cs @@ -1,32 +1,24 @@ -using Avalonia.Controls; -using Avalonia.Controls.Shapes; using Avalonia.Input; using Avalonia.Markup.Xaml; using Avalonia.ReactiveUI; namespace Artemis.UI.Screens.ProfileEditor.Properties.Timeline.Segments; -public class StartSegmentView : ReactiveUserControl +public partial class StartSegmentView : ReactiveUserControl { - private readonly Rectangle _keyframeDragAnchor; private double _dragOffset; public StartSegmentView() { InitializeComponent(); - _keyframeDragAnchor = this.Get("KeyframeDragAnchor"); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } private void KeyframeDragAnchor_OnPointerPressed(object? sender, PointerPressedEventArgs e) { if (ViewModel == null || !e.GetCurrentPoint(this).Properties.IsLeftButtonPressed) return; - e.Pointer.Capture(_keyframeDragAnchor); + e.Pointer.Capture(KeyframeDragAnchor); _dragOffset = ViewModel.Width - e.GetCurrentPoint(this).Position.X; ViewModel.StartResize(); @@ -34,14 +26,14 @@ public class StartSegmentView : ReactiveUserControl private void KeyframeDragAnchor_OnPointerMoved(object? sender, PointerEventArgs e) { - if (ViewModel == null || !ReferenceEquals(e.Pointer.Captured, _keyframeDragAnchor)) + if (ViewModel == null || !ReferenceEquals(e.Pointer.Captured, KeyframeDragAnchor)) return; ViewModel.UpdateResize(e.GetCurrentPoint(this).Position.X + _dragOffset, e.KeyModifiers.HasFlag(KeyModifiers.Shift), e.KeyModifiers.HasFlag(KeyModifiers.Control)); } private void KeyframeDragAnchor_OnPointerReleased(object? sender, PointerReleasedEventArgs e) { - if (ViewModel == null || !ReferenceEquals(e.Pointer.Captured, _keyframeDragAnchor)) + if (ViewModel == null || !ReferenceEquals(e.Pointer.Captured, KeyframeDragAnchor)) return; e.Pointer.Capture(null); ViewModel.FinishResize(e.GetCurrentPoint(this).Position.X + _dragOffset, e.KeyModifiers.HasFlag(KeyModifiers.Shift), e.KeyModifiers.HasFlag(KeyModifiers.Control)); diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/Segments/StartSegmentViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/Segments/StartSegmentViewModel.cs index fcff6ebc4..38acf3c31 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/Segments/StartSegmentViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/Segments/StartSegmentViewModel.cs @@ -1,10 +1,10 @@ using System; +using System.Reactive.Disposables; using System.Reactive.Linq; using Artemis.Core; using Artemis.UI.Shared.Services; using Artemis.UI.Shared.Services.ProfileEditor; using Artemis.UI.Shared.Services.ProfileEditor.Commands; -using Avalonia.Controls.Mixins; using ReactiveUI; namespace Artemis.UI.Screens.ProfileEditor.Properties.Timeline.Segments; diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/Segments/TimelineSegmentViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/Segments/TimelineSegmentViewModel.cs index b2d7687f4..be9c471d4 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/Segments/TimelineSegmentViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/Segments/TimelineSegmentViewModel.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Reactive; +using System.Reactive.Disposables; using System.Reactive.Linq; using System.Threading.Tasks; using Artemis.Core; @@ -11,7 +12,6 @@ using Artemis.UI.Shared.Services; using Artemis.UI.Shared.Services.Builders; using Artemis.UI.Shared.Services.ProfileEditor; using Artemis.UI.Shared.Services.ProfileEditor.Commands; -using Avalonia.Controls.Mixins; using ReactiveUI; namespace Artemis.UI.Screens.ProfileEditor.Properties.Timeline.Segments; diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/TimelineGroupView.axaml.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/TimelineGroupView.axaml.cs index 8999b791a..327a9ef5b 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/TimelineGroupView.axaml.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/TimelineGroupView.axaml.cs @@ -3,15 +3,11 @@ using Avalonia.ReactiveUI; namespace Artemis.UI.Screens.ProfileEditor.Properties.Timeline; -public class TimelineGroupView : ReactiveUserControl +public partial class TimelineGroupView : ReactiveUserControl { public TimelineGroupView() { InitializeComponent(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/TimelineGroupViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/TimelineGroupViewModel.cs index 5370999e3..620be7f41 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/TimelineGroupViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/TimelineGroupViewModel.cs @@ -1,8 +1,8 @@ using System; using System.Collections.ObjectModel; +using System.Reactive.Disposables; using Artemis.UI.Shared; using Artemis.UI.Shared.Services.ProfileEditor; -using Avalonia.Controls.Mixins; using DynamicData; using DynamicData.Binding; using ReactiveUI; diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/TimelinePropertyView.axaml.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/TimelinePropertyView.axaml.cs index 082ad8d15..8bb5494d0 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/TimelinePropertyView.axaml.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/TimelinePropertyView.axaml.cs @@ -3,15 +3,11 @@ using Avalonia.ReactiveUI; namespace Artemis.UI.Screens.ProfileEditor.Properties.Timeline; -public class TimelinePropertyView : ReactiveUserControl +public partial class TimelinePropertyView : ReactiveUserControl { public TimelinePropertyView() { InitializeComponent(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/TimelinePropertyViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/TimelinePropertyViewModel.cs index 211c91130..4ae156667 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/TimelinePropertyViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/TimelinePropertyViewModel.cs @@ -2,12 +2,12 @@ using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; +using System.Reactive.Disposables; using System.Reactive.Linq; using Artemis.Core; using Artemis.UI.Screens.ProfileEditor.Properties.Timeline.Keyframes; using Artemis.UI.Shared; using Artemis.UI.Shared.Services.ProfileEditor; -using Avalonia.Controls.Mixins; using DynamicData; using ReactiveUI; diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/TimelineView.axaml.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/TimelineView.axaml.cs index 9b1d11f85..dce407954 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/TimelineView.axaml.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/TimelineView.axaml.cs @@ -1,31 +1,23 @@ using System.Collections.Generic; using System.Linq; using Artemis.UI.Screens.ProfileEditor.Properties.Timeline.Keyframes; -using Artemis.UI.Shared; using Artemis.UI.Shared.Events; using Artemis.UI.Shared.Extensions; using Avalonia; -using Avalonia.Controls; using Avalonia.Input; using Avalonia.Markup.Xaml; using Avalonia.ReactiveUI; +using Avalonia.VisualTree; namespace Artemis.UI.Screens.ProfileEditor.Properties.Timeline; -public class TimelineView : ReactiveUserControl +public partial class TimelineView : ReactiveUserControl { - private readonly SelectionRectangle _selectionRectangle; - public TimelineView() { InitializeComponent(); - _selectionRectangle = this.Get("SelectionRectangle"); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } private void SelectionRectangle_OnSelectionFinished(object? sender, SelectionRectangleEventArgs e) { @@ -34,7 +26,8 @@ public class TimelineView : ReactiveUserControl List keyframeViews = this.GetVisualChildrenOfType().Where(k => { - Rect hitTestRect = k.TransformedBounds != null ? k.TransformedBounds.Value.Bounds.TransformToAABB(k.TransformedBounds.Value.Transform) : Rect.Empty; + TransformedBounds? transformedBounds = k.GetTransformedBounds(); + Rect hitTestRect = transformedBounds != null ? transformedBounds.Value.Bounds.TransformToAABB(transformedBounds.Value.Transform) : new Rect(); return e.AbsoluteRectangle.Intersects(hitTestRect); }).ToList(); @@ -43,7 +36,7 @@ public class TimelineView : ReactiveUserControl private void InputElement_OnPointerReleased(object? sender, PointerReleasedEventArgs e) { - if (_selectionRectangle.IsSelecting) + if (SelectionRectangle.IsSelecting) return; ViewModel?.SelectKeyframes(new List(), false); diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/TimelineViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/TimelineViewModel.cs index cc7e0dd4d..ec06ddc2b 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/TimelineViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/TimelineViewModel.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Reactive; +using System.Reactive.Disposables; using System.Reactive.Linq; using System.Threading.Tasks; using Artemis.Core; @@ -14,7 +15,6 @@ using Artemis.UI.Shared; using Artemis.UI.Shared.Extensions; using Artemis.UI.Shared.Services.ProfileEditor; using Avalonia; -using Avalonia.Controls.Mixins; using ReactiveUI; namespace Artemis.UI.Screens.ProfileEditor.Properties.Timeline; diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Tree/ContentDialogs/LayerEffectRenameView.axaml.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Tree/ContentDialogs/LayerEffectRenameView.axaml.cs index 425743459..19972807c 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Tree/ContentDialogs/LayerEffectRenameView.axaml.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Tree/ContentDialogs/LayerEffectRenameView.axaml.cs @@ -1,6 +1,5 @@ using System.Threading.Tasks; using Artemis.UI.Shared.Extensions; -using Avalonia.Controls; using Avalonia.Markup.Xaml; using Avalonia.ReactiveUI; using Avalonia.Threading; @@ -8,7 +7,7 @@ using ReactiveUI; namespace Artemis.UI.Screens.ProfileEditor.Properties.Tree.ContentDialogs; -public class LayerEffectRenameView : ReactiveUserControl +public partial class LayerEffectRenameView : ReactiveUserControl { public LayerEffectRenameView() { @@ -24,12 +23,8 @@ public class LayerEffectRenameView : ReactiveUserControl("NameTextBox").SelectAll(); - this.Get("NameTextBox").Focus(); + NameTextBox.SelectAll(); + NameTextBox.Focus(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Tree/Dialogs/LayerBrushPresetView.axaml.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Tree/Dialogs/LayerBrushPresetView.axaml.cs index 50927e5d5..9f25e9c19 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Tree/Dialogs/LayerBrushPresetView.axaml.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Tree/Dialogs/LayerBrushPresetView.axaml.cs @@ -6,17 +6,13 @@ using Avalonia.ReactiveUI; namespace Artemis.UI.Screens.ProfileEditor.Properties.Tree.Dialogs; -public class LayerBrushPresetView : ReactiveUserControl +public partial class LayerBrushPresetView : ReactiveUserControl { public LayerBrushPresetView() { InitializeComponent(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } private void InputElement_OnPointerReleased(object? sender, PointerReleasedEventArgs e) { diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Tree/TreeGroupView.axaml.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Tree/TreeGroupView.axaml.cs index 2e6219049..eb5e233a1 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Tree/TreeGroupView.axaml.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Tree/TreeGroupView.axaml.cs @@ -4,17 +4,13 @@ using Avalonia.ReactiveUI; namespace Artemis.UI.Screens.ProfileEditor.Properties.Tree; -public class TreeGroupView : ReactiveUserControl +public partial class TreeGroupView : ReactiveUserControl { public TreeGroupView() { InitializeComponent(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } private void InputElement_OnPointerPressed(object? sender, PointerPressedEventArgs e) { diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Tree/TreePropertyView.axaml.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Tree/TreePropertyView.axaml.cs index 4e0354fcf..0a42de288 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Tree/TreePropertyView.axaml.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Tree/TreePropertyView.axaml.cs @@ -1,9 +1,8 @@ using System; +using System.Reactive.Disposables; using System.Reactive.Linq; using Artemis.Core; using Avalonia.Controls; -using Avalonia.Controls.Mixins; -using Avalonia.Controls.Primitives; using Avalonia.Interactivity; using Avalonia.Markup.Xaml; using Avalonia.ReactiveUI; @@ -11,7 +10,7 @@ using ReactiveUI; namespace Artemis.UI.Screens.ProfileEditor.Properties.Tree; -public class TreePropertyView : ReactiveUserControl +public partial class TreePropertyView : ReactiveUserControl { public TreePropertyView() { @@ -24,14 +23,10 @@ public class TreePropertyView : ReactiveUserControl }); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } private void DataBindingToggleButton_OnClick(object? sender, RoutedEventArgs e) { ViewModel?.ToggleCurrentLayerProperty(); - this.Find("DataBindingToggleButton").IsChecked = !this.Find("DataBindingToggleButton").IsChecked; + DataBindingToggleButton.IsChecked = !DataBindingToggleButton.IsChecked; } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Tree/TreePropertyViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Tree/TreePropertyViewModel.cs index 983c476ab..ecceb942b 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Tree/TreePropertyViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Tree/TreePropertyViewModel.cs @@ -1,5 +1,6 @@ using System; using System.Reactive; +using System.Reactive.Disposables; using System.Reactive.Linq; using Artemis.Core; using Artemis.UI.Extensions; @@ -7,7 +8,6 @@ using Artemis.UI.Shared; using Artemis.UI.Shared.Services.ProfileEditor; using Artemis.UI.Shared.Services.ProfileEditor.Commands; using Artemis.UI.Shared.Services.PropertyInput; -using Avalonia.Controls.Mixins; using ReactiveUI; namespace Artemis.UI.Screens.ProfileEditor.Properties.Tree; diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Windows/BrushConfigurationWindowView.axaml b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Windows/BrushConfigurationWindowView.axaml index 863c6d768..9395cb9a5 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Windows/BrushConfigurationWindowView.axaml +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Windows/BrushConfigurationWindowView.axaml @@ -1,8 +1,8 @@ - - \ No newline at end of file + \ No newline at end of file diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Windows/BrushConfigurationWindowView.axaml.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Windows/BrushConfigurationWindowView.axaml.cs index 5c6049bf7..d01dc274c 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Windows/BrushConfigurationWindowView.axaml.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Windows/BrushConfigurationWindowView.axaml.cs @@ -5,7 +5,7 @@ using Avalonia.Markup.Xaml; namespace Artemis.UI.Screens.ProfileEditor.Properties.Windows; -public class BrushConfigurationWindowView : ReactiveCoreWindow +public partial class BrushConfigurationWindowView : ReactiveAppWindow { private bool _canClose; diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Windows/EffectConfigurationWindowView.axaml b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Windows/EffectConfigurationWindowView.axaml index 6e6289fd7..a6ef2ccd7 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Windows/EffectConfigurationWindowView.axaml +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Windows/EffectConfigurationWindowView.axaml @@ -1,8 +1,8 @@ - - \ No newline at end of file + \ No newline at end of file diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Windows/EffectConfigurationWindowView.axaml.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Windows/EffectConfigurationWindowView.axaml.cs index dc9cfb0cd..ddee1ec69 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Windows/EffectConfigurationWindowView.axaml.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Windows/EffectConfigurationWindowView.axaml.cs @@ -5,7 +5,7 @@ using Avalonia.Markup.Xaml; namespace Artemis.UI.Screens.ProfileEditor.Properties.Windows; -public class EffectConfigurationWindowView : ReactiveCoreWindow +public partial class EffectConfigurationWindowView : ReactiveAppWindow { private bool _canClose; diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/StatusBar/StatusBarView.axaml.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/StatusBar/StatusBarView.axaml.cs index 7ada29b7d..088f7b1bc 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/StatusBar/StatusBarView.axaml.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/StatusBar/StatusBarView.axaml.cs @@ -3,15 +3,11 @@ using Avalonia.ReactiveUI; namespace Artemis.UI.Screens.ProfileEditor.StatusBar; -public class StatusBarView : ReactiveUserControl +public partial class StatusBarView : ReactiveUserControl { public StatusBarView() { InitializeComponent(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/StatusBar/StatusBarViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/StatusBar/StatusBarViewModel.cs index 341aef64c..73327e70a 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/StatusBar/StatusBarViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/StatusBar/StatusBarViewModel.cs @@ -1,9 +1,9 @@ using System; +using System.Reactive.Disposables; using System.Reactive.Linq; using Artemis.Core; using Artemis.UI.Shared; using Artemis.UI.Shared.Services.ProfileEditor; -using Avalonia.Controls.Mixins; using ReactiveUI; namespace Artemis.UI.Screens.ProfileEditor.StatusBar; diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Tools/SelectionAddToolView.axaml.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Tools/SelectionAddToolView.axaml.cs index b8938f4f5..c7399853d 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Tools/SelectionAddToolView.axaml.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Tools/SelectionAddToolView.axaml.cs @@ -6,17 +6,13 @@ using Avalonia.Skia; namespace Artemis.UI.Screens.ProfileEditor.VisualEditor.Tools; -public class SelectionAddToolView : ReactiveUserControl +public partial class SelectionAddToolView : ReactiveUserControl { public SelectionAddToolView() { InitializeComponent(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } private void SelectionRectangle_OnSelectionFinished(object? sender, SelectionRectangleEventArgs e) { diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Tools/SelectionAddToolViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Tools/SelectionAddToolViewModel.cs index 72da9f522..b1bdf7297 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Tools/SelectionAddToolViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Tools/SelectionAddToolViewModel.cs @@ -1,12 +1,12 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Reactive.Disposables; using System.Reactive.Linq; using Artemis.Core; using Artemis.Core.Services; using Artemis.UI.Shared.Services.ProfileEditor; using Artemis.UI.Shared.Services.ProfileEditor.Commands; -using Avalonia.Controls.Mixins; using Material.Icons; using ReactiveUI; using SkiaSharp; diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Tools/SelectionRemoveToolView.axaml.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Tools/SelectionRemoveToolView.axaml.cs index 4a618dd3f..a0c64e88a 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Tools/SelectionRemoveToolView.axaml.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Tools/SelectionRemoveToolView.axaml.cs @@ -5,17 +5,13 @@ using Avalonia.Skia; namespace Artemis.UI.Screens.ProfileEditor.VisualEditor.Tools; -public class SelectionRemoveToolView : ReactiveUserControl +public partial class SelectionRemoveToolView : ReactiveUserControl { public SelectionRemoveToolView() { InitializeComponent(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } private void SelectionRectangle_OnSelectionFinished(object? sender, SelectionRectangleEventArgs e) { diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Tools/SelectionRemoveToolViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Tools/SelectionRemoveToolViewModel.cs index 7fde8511e..2c7d0a995 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Tools/SelectionRemoveToolViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Tools/SelectionRemoveToolViewModel.cs @@ -1,11 +1,11 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Reactive.Disposables; using System.Reactive.Linq; using Artemis.Core; using Artemis.UI.Shared.Services.ProfileEditor; using Artemis.UI.Shared.Services.ProfileEditor.Commands; -using Avalonia.Controls.Mixins; using Material.Icons; using ReactiveUI; using SkiaSharp; diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Tools/TransformToolView.axaml.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Tools/TransformToolView.axaml.cs index 26bf273cc..c4af9f2bf 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Tools/TransformToolView.axaml.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Tools/TransformToolView.axaml.cs @@ -1,11 +1,11 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Reactive.Disposables; using Artemis.Core; using Artemis.UI.Shared.Extensions; using Avalonia; using Avalonia.Controls; -using Avalonia.Controls.Mixins; using Avalonia.Controls.PanAndZoom; using Avalonia.Controls.Shapes; using Avalonia.Input; @@ -21,19 +21,9 @@ using SkiaSharp; namespace Artemis.UI.Screens.ProfileEditor.VisualEditor.Tools; -public class TransformToolView : ReactiveUserControl +public partial class TransformToolView : ReactiveUserControl { - private readonly Grid _handleGrid; private readonly List _handles = new(); - private readonly Panel _resizeBottomCenter; - private readonly Panel _resizeBottomLeft; - private readonly Panel _resizeBottomRight; - private readonly Panel _resizeLeftCenter; - private readonly Panel _resizeRightCenter; - private readonly Panel _resizeTopCenter; - private readonly Panel _resizeTopLeft; - private readonly Panel _resizeTopRight; - private SKPoint _dragOffset; private ZoomBorder? _zoomBorder; @@ -41,31 +31,21 @@ public class TransformToolView : ReactiveUserControl { InitializeComponent(); - _handleGrid = this.Get("HandleGrid"); + _handles.Add(RotateTopLeft); + _handles.Add(RotateTopRight); + _handles.Add(RotateBottomRight); + _handles.Add(RotateBottomLeft); - _handles.Add(this.Get("RotateTopLeft")); - _handles.Add(this.Get("RotateTopRight")); - _handles.Add(this.Get("RotateBottomRight")); - _handles.Add(this.Get("RotateBottomLeft")); + _handles.Add(ResizeTopCenter); + _handles.Add(ResizeRightCenter); + _handles.Add(ResizeBottomCenter); + _handles.Add(ResizeLeftCenter); + _handles.Add(ResizeTopLeft); + _handles.Add(ResizeTopRight); + _handles.Add(ResizeBottomRight); + _handles.Add(ResizeBottomLeft); - _resizeTopCenter = this.Get("ResizeTopCenter"); - _handles.Add(_resizeTopCenter); - _resizeRightCenter = this.Get("ResizeRightCenter"); - _handles.Add(_resizeRightCenter); - _resizeBottomCenter = this.Get("ResizeBottomCenter"); - _handles.Add(_resizeBottomCenter); - _resizeLeftCenter = this.Get("ResizeLeftCenter"); - _handles.Add(_resizeLeftCenter); - _resizeTopLeft = this.Get("ResizeTopLeft"); - _handles.Add(_resizeTopLeft); - _resizeTopRight = this.Get("ResizeTopRight"); - _handles.Add(_resizeTopRight); - _resizeBottomRight = this.Get("ResizeBottomRight"); - _handles.Add(_resizeBottomRight); - _resizeBottomLeft = this.Get("ResizeBottomLeft"); - _handles.Add(_resizeBottomLeft); - - _handles.Add(this.Get("AnchorPoint")); + _handles.Add(AnchorPoint); this.WhenActivated(d => ViewModel.WhenAnyValue(vm => vm.Rotation).Subscribe(_ => UpdateTransforms()).DisposeWith(d)); } @@ -83,17 +63,13 @@ public class TransformToolView : ReactiveUserControl RotateTransform counterRotate = new(ViewModel.Rotation * -1); // Apply the counter rotation to the containers - foreach (Panel panel in _handleGrid.Children.Where(c => c is Panel and not Canvas).Cast()) + foreach (Panel panel in HandleGrid.Children.Where(c => c is Panel and not Canvas).Cast()) panel.RenderTransform = counterRotate; - foreach (Control control in _handleGrid.GetVisualDescendants().Where(d => d is Control c && c.Classes.Contains("unscaled")).Cast()) + foreach (Control control in HandleGrid.GetVisualDescendants().Where(d => d is Control c && c.Classes.Contains("unscaled")).Cast()) control.RenderTransform = counterScale; } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } private SKPoint GetPositionForViewModel(PointerEventArgs e) { @@ -117,21 +93,21 @@ public class TransformToolView : ReactiveUserControl private TransformToolViewModel.ResizeSide GetResizeDirection(Ellipse element) { - if (ReferenceEquals(element.Parent, _resizeTopLeft)) + if (ReferenceEquals(element.Parent, ResizeTopLeft)) return TransformToolViewModel.ResizeSide.Top | TransformToolViewModel.ResizeSide.Left; - if (ReferenceEquals(element.Parent, _resizeTopRight)) + if (ReferenceEquals(element.Parent, ResizeTopRight)) return TransformToolViewModel.ResizeSide.Top | TransformToolViewModel.ResizeSide.Right; - if (ReferenceEquals(element.Parent, _resizeBottomRight)) + if (ReferenceEquals(element.Parent, ResizeBottomRight)) return TransformToolViewModel.ResizeSide.Bottom | TransformToolViewModel.ResizeSide.Right; - if (ReferenceEquals(element.Parent, _resizeBottomLeft)) + if (ReferenceEquals(element.Parent, ResizeBottomLeft)) return TransformToolViewModel.ResizeSide.Bottom | TransformToolViewModel.ResizeSide.Left; - if (ReferenceEquals(element.Parent, _resizeTopCenter)) + if (ReferenceEquals(element.Parent, ResizeTopCenter)) return TransformToolViewModel.ResizeSide.Top; - if (ReferenceEquals(element.Parent, _resizeRightCenter)) + if (ReferenceEquals(element.Parent, ResizeRightCenter)) return TransformToolViewModel.ResizeSide.Right; - if (ReferenceEquals(element.Parent, _resizeBottomCenter)) + if (ReferenceEquals(element.Parent, ResizeBottomCenter)) return TransformToolViewModel.ResizeSide.Bottom; - if (ReferenceEquals(element.Parent, _resizeLeftCenter)) + if (ReferenceEquals(element.Parent, ResizeLeftCenter)) return TransformToolViewModel.ResizeSide.Left; throw new ArgumentException("Given element is not a child of a resize container"); @@ -310,14 +286,14 @@ public class TransformToolView : ReactiveUserControl private void UpdateCursors() { - _resizeTopCenter.Cursor = GetCursorAtAngle(0f); - _resizeTopRight.Cursor = GetCursorAtAngle(45f); - _resizeRightCenter.Cursor = GetCursorAtAngle(90f); - _resizeBottomRight.Cursor = GetCursorAtAngle(135f); - _resizeBottomCenter.Cursor = GetCursorAtAngle(180f); - _resizeBottomLeft.Cursor = GetCursorAtAngle(225f); - _resizeLeftCenter.Cursor = GetCursorAtAngle(270f); - _resizeTopLeft.Cursor = GetCursorAtAngle(315f); + ResizeTopCenter.Cursor = GetCursorAtAngle(0f); + ResizeTopRight.Cursor = GetCursorAtAngle(45f); + ResizeRightCenter.Cursor = GetCursorAtAngle(90f); + ResizeBottomRight.Cursor = GetCursorAtAngle(135f); + ResizeBottomCenter.Cursor = GetCursorAtAngle(180f); + ResizeBottomLeft.Cursor = GetCursorAtAngle(225f); + ResizeLeftCenter.Cursor = GetCursorAtAngle(270f); + ResizeTopLeft.Cursor = GetCursorAtAngle(315f); } private Cursor GetCursorAtAngle(float angle, bool includeLayerRotation = true) diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Tools/TransformToolViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Tools/TransformToolViewModel.cs index b5f737603..7475f15eb 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Tools/TransformToolViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Tools/TransformToolViewModel.cs @@ -1,5 +1,6 @@ using System; using System.Reactive; +using System.Reactive.Disposables; using System.Reactive.Linq; using Artemis.Core; using Artemis.UI.Exceptions; @@ -7,7 +8,6 @@ using Artemis.UI.Shared.Extensions; using Artemis.UI.Shared.Services.ProfileEditor; using Artemis.UI.Shared.Services.ProfileEditor.Commands; using Avalonia; -using Avalonia.Controls.Mixins; using Material.Icons; using ReactiveUI; using SkiaSharp; diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/VisualEditorView.axaml b/src/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/VisualEditorView.axaml index 7b79b8273..b8e1c5756 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/VisualEditorView.axaml +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/VisualEditorView.axaml @@ -84,11 +84,7 @@ - + diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/VisualEditorView.axaml.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/VisualEditorView.axaml.cs index 28696008f..3fb88d5c5 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/VisualEditorView.axaml.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/VisualEditorView.axaml.cs @@ -2,7 +2,6 @@ using System; using System.Linq; using System.Reactive.Disposables; using Avalonia; -using Avalonia.Controls; using Avalonia.Controls.PanAndZoom; using Avalonia.Input; using Avalonia.Markup.Xaml; @@ -13,19 +12,17 @@ using ReactiveUI; namespace Artemis.UI.Screens.ProfileEditor.VisualEditor; -public class VisualEditorView : ReactiveUserControl +public partial class VisualEditorView : ReactiveUserControl { - private readonly ZoomBorder _zoomBorder; private bool _movedByUser; public VisualEditorView() { InitializeComponent(); - - _zoomBorder = this.Find("ZoomBorder"); - _zoomBorder.PropertyChanged += ZoomBorderOnPropertyChanged; - _zoomBorder.PointerMoved += ZoomBorderOnPointerMoved; - _zoomBorder.PointerWheelChanged += ZoomBorderOnPointerWheelChanged; + + ZoomBorder.PropertyChanged += ZoomBorderOnPropertyChanged; + ZoomBorder.PointerMoved += ZoomBorderOnPointerMoved; + ZoomBorder.PointerWheelChanged += ZoomBorderOnPointerWheelChanged; UpdateZoomBorderBackground(); this.WhenActivated(d => @@ -48,7 +45,7 @@ public class VisualEditorView : ReactiveUserControl private void ZoomBorderOnPointerMoved(object? sender, PointerEventArgs e) { - if (e.GetCurrentPoint(_zoomBorder).Properties.IsMiddleButtonPressed) + if (e.GetCurrentPoint(ZoomBorder).Properties.IsMiddleButtonPressed) _movedByUser = true; } @@ -59,20 +56,16 @@ public class VisualEditorView : ReactiveUserControl private void ZoomBorderOnPropertyChanged(object? sender, AvaloniaPropertyChangedEventArgs e) { - if (e.Property.Name == nameof(_zoomBorder.Background)) + if (e.Property.Name == nameof(ZoomBorder.Background)) UpdateZoomBorderBackground(); } private void UpdateZoomBorderBackground() { - if (_zoomBorder.Background is VisualBrush visualBrush) - visualBrush.DestinationRect = new RelativeRect(_zoomBorder.OffsetX * -1, _zoomBorder.OffsetY * -1, 20, 20, RelativeUnit.Absolute); + if (ZoomBorder.Background is VisualBrush visualBrush) + visualBrush.DestinationRect = new RelativeRect(ZoomBorder.OffsetX * -1, ZoomBorder.OffsetY * -1, 20, 20, RelativeUnit.Absolute); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } private void ZoomBorder_OnZoomChanged(object sender, ZoomChangedEventArgs e) { @@ -96,8 +89,8 @@ public class VisualEditorView : ReactiveUserControl double scale = Math.Min(3, Math.Min(Bounds.Width / scriptRect.Width, Bounds.Height / scriptRect.Height)); // Pan and zoom to make the script fit - _zoomBorder.Zoom(scale, 0, 0, skipTransitions); - _zoomBorder.Pan(Bounds.Center.X - scriptRect.Center.X * scale, Bounds.Center.Y - scriptRect.Center.Y * scale, skipTransitions); + ZoomBorder.Zoom(scale, 0, 0, skipTransitions); + ZoomBorder.Pan(Bounds.Center.X - scriptRect.Center.X * scale, Bounds.Center.Y - scriptRect.Center.Y * scale, skipTransitions); _movedByUser = false; } diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Visualizers/LayerShapeVisualizerView.axaml.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Visualizers/LayerShapeVisualizerView.axaml.cs index 3c35220b9..e91f55ffb 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Visualizers/LayerShapeVisualizerView.axaml.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Visualizers/LayerShapeVisualizerView.axaml.cs @@ -1,10 +1,8 @@ using System; using System.Linq; +using System.Reactive.Disposables; using Avalonia; -using Avalonia.Controls; -using Avalonia.Controls.Mixins; using Avalonia.Controls.PanAndZoom; -using Avalonia.Controls.Shapes; using Avalonia.LogicalTree; using Avalonia.Markup.Xaml; using Avalonia.ReactiveUI; @@ -12,25 +10,16 @@ using ReactiveUI; namespace Artemis.UI.Screens.ProfileEditor.VisualEditor.Visualizers; -public class LayerShapeVisualizerView : ReactiveUserControl +public partial class LayerShapeVisualizerView : ReactiveUserControl { - private readonly Path _layerVisualizer; - private readonly Path _layerVisualizerUnbound; private ZoomBorder? _zoomBorder; public LayerShapeVisualizerView() { InitializeComponent(); - _layerVisualizer = this.Get("LayerVisualizer"); - _layerVisualizerUnbound = this.Get("LayerVisualizerUnbound"); - this.WhenActivated(d => ViewModel.WhenAnyValue(vm => vm.Selected).Subscribe(_ => UpdateStrokeThickness()).DisposeWith(d)); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } #region Overrides of TemplatedControl @@ -66,13 +55,13 @@ public class LayerShapeVisualizerView : ReactiveUserControl +public partial class LayerVisualizerView : ReactiveUserControl { - private readonly Path _layerVisualizer; private ZoomBorder? _zoomBorder; public LayerVisualizerView() { InitializeComponent(); - _layerVisualizer = this.Get("LayerVisualizer"); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } #region Overrides of TemplatedControl @@ -49,7 +41,7 @@ public class LayerVisualizerView : ReactiveUserControl { if (e.Property != ZoomBorder.ZoomXProperty || _zoomBorder == null) return; - _layerVisualizer.StrokeThickness = Math.Max(1, 4 / _zoomBorder.ZoomX); + LayerVisualizer.StrokeThickness = Math.Max(1, 4 / _zoomBorder.ZoomX); } #endregion diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Visualizers/LayerVisualizerViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Visualizers/LayerVisualizerViewModel.cs index 60203a62f..fd6044730 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Visualizers/LayerVisualizerViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Visualizers/LayerVisualizerViewModel.cs @@ -1,11 +1,11 @@ using System; +using System.Reactive.Disposables; using System.Reactive.Linq; using Artemis.Core; using Artemis.UI.Shared; using Artemis.UI.Shared.Extensions; using Artemis.UI.Shared.Services.ProfileEditor; using Avalonia; -using Avalonia.Controls.Mixins; using ReactiveUI; using SkiaSharp; diff --git a/src/Artemis.UI/Screens/ProfileEditor/ProfileEditorTitleBarView.axaml b/src/Artemis.UI/Screens/ProfileEditor/ProfileEditorTitleBarView.axaml index a4add314f..3a69989c8 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/ProfileEditorTitleBarView.axaml +++ b/src/Artemis.UI/Screens/ProfileEditor/ProfileEditorTitleBarView.axaml @@ -3,15 +3,18 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:avalonia="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia" + xmlns:windowing="clr-namespace:FluentAvalonia.UI.Windowing;assembly=FluentAvalonia" + xmlns:profileEditor="clr-namespace:Artemis.UI.Screens.ProfileEditor" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" - x:Class="Artemis.UI.Screens.ProfileEditor.ProfileEditorTitleBarView"> - - - - - - - diff --git a/src/Artemis.UI/Screens/ProfileEditor/ProfileEditorTitleBarView.axaml.cs b/src/Artemis.UI/Screens/ProfileEditor/ProfileEditorTitleBarView.axaml.cs index 9ac61e1f6..1cf5dae03 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/ProfileEditorTitleBarView.axaml.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/ProfileEditorTitleBarView.axaml.cs @@ -1,22 +1,13 @@ using Avalonia.Controls; -using Avalonia.Interactivity; using Avalonia.Markup.Xaml; namespace Artemis.UI.Screens.ProfileEditor; -public class ProfileEditorTitleBarView : UserControl +public partial class ProfileEditorTitleBarView : UserControl { public ProfileEditorTitleBarView() { InitializeComponent(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } - - private void MenuItem_OnSubmenuOpened(object? sender, RoutedEventArgs e) - { - } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/ProfileEditor/ProfileEditorView.axaml b/src/Artemis.UI/Screens/ProfileEditor/ProfileEditorView.axaml index 3f857f1d2..2e6af4e05 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/ProfileEditorView.axaml +++ b/src/Artemis.UI/Screens/ProfileEditor/ProfileEditorView.axaml @@ -8,8 +8,7 @@ xmlns:shared="clr-namespace:Artemis.UI.Shared.Services.ProfileEditor;assembly=Artemis.UI.Shared" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" x:Class="Artemis.UI.Screens.ProfileEditor.ProfileEditorView" - x:DataType="profileEditor:ProfileEditorViewModel" - Name="ProfileEditorView"> + x:DataType="profileEditor:ProfileEditorViewModel"> diff --git a/src/Artemis.UI/Screens/ProfileEditor/ProfileEditorView.axaml.cs b/src/Artemis.UI/Screens/ProfileEditor/ProfileEditorView.axaml.cs index e745f4d2f..31ae91870 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/ProfileEditorView.axaml.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/ProfileEditorView.axaml.cs @@ -1,11 +1,10 @@ using Avalonia; -using Avalonia.Interactivity; using Avalonia.Markup.Xaml; using Avalonia.ReactiveUI; namespace Artemis.UI.Screens.ProfileEditor; -public class ProfileEditorView : ReactiveUserControl +public partial class ProfileEditorView : ReactiveUserControl { public ProfileEditorView() { @@ -23,12 +22,4 @@ public class ProfileEditorView : ReactiveUserControl #endregion - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } - - private void MenuItem_OnSubmenuOpened(object? sender, RoutedEventArgs e) - { - } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Root/DefaultTitleBarView.axaml b/src/Artemis.UI/Screens/Root/DefaultTitleBarView.axaml index 1bfa0720c..057fca3d0 100644 --- a/src/Artemis.UI/Screens/Root/DefaultTitleBarView.axaml +++ b/src/Artemis.UI/Screens/Root/DefaultTitleBarView.axaml @@ -3,9 +3,10 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:avalonia="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia" + xmlns:windowing="clr-namespace:FluentAvalonia.UI.Windowing;assembly=FluentAvalonia" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" x:Class="Artemis.UI.Screens.Root.DefaultTitleBarView"> - \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Root/DefaultTitleBarView.axaml.cs b/src/Artemis.UI/Screens/Root/DefaultTitleBarView.axaml.cs index a4aa18dfc..f4bfd4e04 100644 --- a/src/Artemis.UI/Screens/Root/DefaultTitleBarView.axaml.cs +++ b/src/Artemis.UI/Screens/Root/DefaultTitleBarView.axaml.cs @@ -3,15 +3,11 @@ using Avalonia.Markup.Xaml; namespace Artemis.UI.Screens.Root; -public class DefaultTitleBarView : UserControl +public partial class DefaultTitleBarView : UserControl { public DefaultTitleBarView() { InitializeComponent(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Root/RootView.axaml.cs b/src/Artemis.UI/Screens/Root/RootView.axaml.cs index a39ad9af7..925fa14ba 100644 --- a/src/Artemis.UI/Screens/Root/RootView.axaml.cs +++ b/src/Artemis.UI/Screens/Root/RootView.axaml.cs @@ -3,15 +3,11 @@ using Avalonia.ReactiveUI; namespace Artemis.UI.Screens.Root; -public class RootView : ReactiveUserControl +public partial class RootView : ReactiveUserControl { public RootView() { InitializeComponent(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Root/SplashView.axaml.cs b/src/Artemis.UI/Screens/Root/SplashView.axaml.cs index a48cd245f..cc54a133c 100644 --- a/src/Artemis.UI/Screens/Root/SplashView.axaml.cs +++ b/src/Artemis.UI/Screens/Root/SplashView.axaml.cs @@ -9,7 +9,7 @@ using ReactiveUI; namespace Artemis.UI.Screens.Root; -public class SplashView : ReactiveWindow +public partial class SplashView : ReactiveWindow { public SplashView() { @@ -25,8 +25,4 @@ public class SplashView : ReactiveWindow }); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Scripting/Dialogs/ScriptConfigurationCreateView.axaml.cs b/src/Artemis.UI/Screens/Scripting/Dialogs/ScriptConfigurationCreateView.axaml.cs index 06c18583a..801279422 100644 --- a/src/Artemis.UI/Screens/Scripting/Dialogs/ScriptConfigurationCreateView.axaml.cs +++ b/src/Artemis.UI/Screens/Scripting/Dialogs/ScriptConfigurationCreateView.axaml.cs @@ -3,15 +3,11 @@ using Avalonia.ReactiveUI; namespace Artemis.UI.Screens.Scripting.Dialogs; -public class ScriptConfigurationCreateView : ReactiveUserControl +public partial class ScriptConfigurationCreateView : ReactiveUserControl { public ScriptConfigurationCreateView() { InitializeComponent(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Scripting/Dialogs/ScriptConfigurationEditView.axaml.cs b/src/Artemis.UI/Screens/Scripting/Dialogs/ScriptConfigurationEditView.axaml.cs index df99ad942..2cebde7ec 100644 --- a/src/Artemis.UI/Screens/Scripting/Dialogs/ScriptConfigurationEditView.axaml.cs +++ b/src/Artemis.UI/Screens/Scripting/Dialogs/ScriptConfigurationEditView.axaml.cs @@ -1,24 +1,19 @@ -using Avalonia.Controls; -using Avalonia.Markup.Xaml; +using Avalonia.Markup.Xaml; using Avalonia.ReactiveUI; using ReactiveUI; namespace Artemis.UI.Screens.Scripting.Dialogs; -public class ScriptConfigurationEditView : ReactiveUserControl +public partial class ScriptConfigurationEditView : ReactiveUserControl { public ScriptConfigurationEditView() { InitializeComponent(); this.WhenActivated(_ => { - this.Get("Input").Focus(); - this.Get("Input").SelectAll(); + Input.Focus(); + Input.SelectAll(); }); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Scripting/ScriptsDialogView.axaml b/src/Artemis.UI/Screens/Scripting/ScriptsDialogView.axaml index 68975d579..22f4d5c00 100644 --- a/src/Artemis.UI/Screens/Scripting/ScriptsDialogView.axaml +++ b/src/Artemis.UI/Screens/Scripting/ScriptsDialogView.axaml @@ -1,11 +1,11 @@ - - \ No newline at end of file + \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Scripting/ScriptsDialogView.axaml.cs b/src/Artemis.UI/Screens/Scripting/ScriptsDialogView.axaml.cs index 706a9a5b5..4010a6c63 100644 --- a/src/Artemis.UI/Screens/Scripting/ScriptsDialogView.axaml.cs +++ b/src/Artemis.UI/Screens/Scripting/ScriptsDialogView.axaml.cs @@ -5,7 +5,7 @@ using Avalonia.Markup.Xaml; namespace Artemis.UI.Screens.Scripting; -public class ScriptsDialogView : ReactiveCoreWindow +public partial class ScriptsDialogView : ReactiveAppWindow { private bool _canClose; @@ -31,8 +31,4 @@ public class ScriptsDialogView : ReactiveCoreWindow } } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Settings/SettingsView.axaml.cs b/src/Artemis.UI/Screens/Settings/SettingsView.axaml.cs index f7f6c2781..5cecc0cd7 100644 --- a/src/Artemis.UI/Screens/Settings/SettingsView.axaml.cs +++ b/src/Artemis.UI/Screens/Settings/SettingsView.axaml.cs @@ -3,15 +3,11 @@ using Avalonia.ReactiveUI; namespace Artemis.UI.Screens.Settings; -public class SettingsView : ReactiveUserControl +public partial class SettingsView : ReactiveUserControl { public SettingsView() { InitializeComponent(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Settings/Tabs/AboutTabView.axaml b/src/Artemis.UI/Screens/Settings/Tabs/AboutTabView.axaml index 3f3571c93..00014fa1e 100644 --- a/src/Artemis.UI/Screens/Settings/Tabs/AboutTabView.axaml +++ b/src/Artemis.UI/Screens/Settings/Tabs/AboutTabView.axaml @@ -29,7 +29,7 @@ - + - + - + +public partial class AboutTabView : ReactiveUserControl { public AboutTabView() { InitializeComponent(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Settings/Tabs/DevicesTabView.axaml.cs b/src/Artemis.UI/Screens/Settings/Tabs/DevicesTabView.axaml.cs index a1d270474..cc8949831 100644 --- a/src/Artemis.UI/Screens/Settings/Tabs/DevicesTabView.axaml.cs +++ b/src/Artemis.UI/Screens/Settings/Tabs/DevicesTabView.axaml.cs @@ -3,15 +3,11 @@ using Avalonia.ReactiveUI; namespace Artemis.UI.Screens.Settings; -public class DevicesTabView : ReactiveUserControl +public partial class DevicesTabView : ReactiveUserControl { public DevicesTabView() { InitializeComponent(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Settings/Tabs/GeneralTabView.axaml b/src/Artemis.UI/Screens/Settings/Tabs/GeneralTabView.axaml index 953f0ac1c..86f46d2bf 100644 --- a/src/Artemis.UI/Screens/Settings/Tabs/GeneralTabView.axaml +++ b/src/Artemis.UI/Screens/Settings/Tabs/GeneralTabView.axaml @@ -28,7 +28,7 @@ - + @@ -39,7 +39,7 @@ OffContent="No" /> - + @@ -60,7 +60,7 @@ sec - + @@ -76,7 +76,7 @@ - + @@ -114,7 +114,7 @@ - + @@ -156,7 +156,7 @@ - + @@ -171,7 +171,7 @@ - + @@ -209,7 +209,7 @@ - + @@ -282,7 +282,7 @@ Items="{CompiledBinding GraphicsContexts}" /> - + @@ -305,7 +305,7 @@ - + @@ -353,7 +353,7 @@ - + @@ -44,6 +44,7 @@ + diff --git a/src/Artemis.UI/Screens/Workshop/WorkshopView.axaml.cs b/src/Artemis.UI/Screens/Workshop/WorkshopView.axaml.cs index c60987a56..c875bd294 100644 --- a/src/Artemis.UI/Screens/Workshop/WorkshopView.axaml.cs +++ b/src/Artemis.UI/Screens/Workshop/WorkshopView.axaml.cs @@ -3,15 +3,11 @@ using Avalonia.ReactiveUI; namespace Artemis.UI.Screens.Workshop; -public class WorkshopView : ReactiveUserControl +public partial class WorkshopView : ReactiveUserControl { public WorkshopView() { InitializeComponent(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } } \ No newline at end of file diff --git a/src/Artemis.UI/Services/Updating/UpdateService.cs b/src/Artemis.UI/Services/Updating/UpdateService.cs index fee0b93b0..15e66985e 100644 --- a/src/Artemis.UI/Services/Updating/UpdateService.cs +++ b/src/Artemis.UI/Services/Updating/UpdateService.cs @@ -5,7 +5,6 @@ using System.Threading; using System.Threading.Tasks; using Artemis.Core; using Artemis.Core.Services; -using Artemis.Storage.Entities.General; using Artemis.Storage.Repositories; using Artemis.UI.Exceptions; using Artemis.UI.Shared.Services.MainWindow; @@ -110,6 +109,9 @@ public class UpdateService : IUpdateService private async void HandleAutoUpdateEvent(object? sender, EventArgs e) { + if (Constants.CurrentVersion == "local") + return; + // The event can trigger from multiple sources with a timer acting as a fallback, only actual perform an action once per max 59 minutes if (DateTime.UtcNow - _lastAutoUpdateCheck < TimeSpan.FromMinutes(59)) return; @@ -204,6 +206,9 @@ public class UpdateService : IUpdateService /// public bool Initialize() { + if (Constants.CurrentVersion == "local") + return false; + string? channelArgument = Constants.StartupArguments.FirstOrDefault(a => a.StartsWith("--channel=")); if (channelArgument != null) Channel = channelArgument.Split("=")[1]; diff --git a/src/Artemis.UI/Styles/Artemis.axaml b/src/Artemis.UI/Styles/Artemis.axaml index d92851a90..242bef032 100644 --- a/src/Artemis.UI/Styles/Artemis.axaml +++ b/src/Artemis.UI/Styles/Artemis.axaml @@ -1,10 +1,11 @@  + xmlns:styling="clr-namespace:FluentAvalonia.Styling;assembly=FluentAvalonia" + xmlns:avalonia="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia"> - + + + - - \ No newline at end of file diff --git a/src/Artemis.UI/Styles/Markdown.axaml b/src/Artemis.UI/Styles/Markdown.axaml deleted file mode 100644 index 34acbe75f..000000000 --- a/src/Artemis.UI/Styles/Markdown.axaml +++ /dev/null @@ -1,191 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ## Core - * Cleaned up ProfileService render condition - * Core - Added fading in and out of profiles - * Core - Apply opacity layer only when fading - * Core - Fixed when condition stops being true mid-fade - * Core - Removed FadingStatus enum - - # General - - Meta - Fixed warnings - - Meta - Update RGB.NET - - # Plugins - - Plugins - Ignore version when loading shared assemblies - - # UI - - Sidebar - Improved category reordering code - - - - - - \ No newline at end of file diff --git a/src/Artemis.UI/ViewLocator.cs b/src/Artemis.UI/ViewLocator.cs index 45ceec2d2..d95012653 100644 --- a/src/Artemis.UI/ViewLocator.cs +++ b/src/Artemis.UI/ViewLocator.cs @@ -11,7 +11,7 @@ namespace Artemis.UI; public class ViewLocator : IDataTemplate { - public IControl Build(object data) + public Control Build(object data) { Type dataType = data.GetType(); string name = dataType.FullName!.Split('`')[0].Replace("ViewModel", "View"); diff --git a/src/Artemis.VisualScripting/Artemis.VisualScripting.csproj b/src/Artemis.VisualScripting/Artemis.VisualScripting.csproj index ac5bb81ea..03500a177 100644 --- a/src/Artemis.VisualScripting/Artemis.VisualScripting.csproj +++ b/src/Artemis.VisualScripting/Artemis.VisualScripting.csproj @@ -1,21 +1,21 @@  - net6.0 + net7.0 enable enable x64 - - - - - - - - + + + + + + + + diff --git a/src/Artemis.VisualScripting/Converters/JsonConverter.cs b/src/Artemis.VisualScripting/Converters/JsonConverter.cs new file mode 100644 index 000000000..f0b9b7820 --- /dev/null +++ b/src/Artemis.VisualScripting/Converters/JsonConverter.cs @@ -0,0 +1,26 @@ +using System.Globalization; +using Artemis.Core; +using Avalonia.Data.Converters; +using Newtonsoft.Json; + +namespace Artemis.VisualScripting.Converters; + +/// +/// Converts input into . +/// +public class JsonConverter : IValueConverter +{ + /// + public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture) + { + return JsonConvert.SerializeObject(value, Formatting.Indented); + } + + /// + public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) + { + if (value == null) + return null; + return JsonConvert.DeserializeObject(value.ToString(), targetType); + } +} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/DryIoc/ContainerExtensions.cs b/src/Artemis.VisualScripting/DryIoc/ContainerExtensions.cs index 0377f56ec..ca4c9845c 100644 --- a/src/Artemis.VisualScripting/DryIoc/ContainerExtensions.cs +++ b/src/Artemis.VisualScripting/DryIoc/ContainerExtensions.cs @@ -24,7 +24,7 @@ public static class ContainerExtensions // Pooling container.RegisterInstance(ObjectPool.Create>()); container.RegisterInstance(ObjectPool.Create>()); - container.RegisterInstance(ObjectPool.Create()); + container.RegisterInstance(ObjectPool.Create()); // Parser container.Register(Reuse.Singleton); @@ -36,5 +36,6 @@ public static class ContainerExtensions // Evaluator container.Register(Reuse.Singleton); + container.Register(Reuse.Singleton); } } \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Color/Screens/ColorGradientNodeCustomView.axaml.cs b/src/Artemis.VisualScripting/Nodes/Color/Screens/ColorGradientNodeCustomView.axaml.cs index 183d660fd..ec578cde5 100644 --- a/src/Artemis.VisualScripting/Nodes/Color/Screens/ColorGradientNodeCustomView.axaml.cs +++ b/src/Artemis.VisualScripting/Nodes/Color/Screens/ColorGradientNodeCustomView.axaml.cs @@ -4,17 +4,13 @@ using Avalonia.ReactiveUI; namespace Artemis.VisualScripting.Nodes.Color.Screens; -public class ColorGradientNodeCustomView : ReactiveUserControl +public partial class ColorGradientNodeCustomView : ReactiveUserControl { public ColorGradientNodeCustomView() { InitializeComponent(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } private void GradientPickerButton_OnFlyoutOpened(GradientPickerButton sender, EventArgs args) { diff --git a/src/Artemis.VisualScripting/Nodes/Color/Screens/RampSKColorNodeCustomView.axaml.cs b/src/Artemis.VisualScripting/Nodes/Color/Screens/RampSKColorNodeCustomView.axaml.cs index b0133dcc3..d70520a1d 100644 --- a/src/Artemis.VisualScripting/Nodes/Color/Screens/RampSKColorNodeCustomView.axaml.cs +++ b/src/Artemis.VisualScripting/Nodes/Color/Screens/RampSKColorNodeCustomView.axaml.cs @@ -4,17 +4,13 @@ using Avalonia.ReactiveUI; namespace Artemis.VisualScripting.Nodes.Color.Screens; -public class RampSKColorNodeCustomView : ReactiveUserControl +public partial class RampSKColorNodeCustomView : ReactiveUserControl { public RampSKColorNodeCustomView() { InitializeComponent(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } private void GradientPickerButton_OnFlyoutOpened(GradientPickerButton sender, EventArgs args) { diff --git a/src/Artemis.VisualScripting/Nodes/DataModel/Screens/DataModelEventCycleNodeCustomView.axaml.cs b/src/Artemis.VisualScripting/Nodes/DataModel/Screens/DataModelEventCycleNodeCustomView.axaml.cs index 3df2bafcc..39c27cb08 100644 --- a/src/Artemis.VisualScripting/Nodes/DataModel/Screens/DataModelEventCycleNodeCustomView.axaml.cs +++ b/src/Artemis.VisualScripting/Nodes/DataModel/Screens/DataModelEventCycleNodeCustomView.axaml.cs @@ -3,15 +3,11 @@ using Avalonia.ReactiveUI; namespace Artemis.VisualScripting.Nodes.DataModel.Screens; -public class DataModelEventCycleNodeCustomView : ReactiveUserControl +public partial class DataModelEventCycleNodeCustomView : ReactiveUserControl { public DataModelEventCycleNodeCustomView() { InitializeComponent(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } } \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/DataModel/Screens/DataModelEventNodeCustomView.axaml.cs b/src/Artemis.VisualScripting/Nodes/DataModel/Screens/DataModelEventNodeCustomView.axaml.cs index fc75675af..62653fdb8 100644 --- a/src/Artemis.VisualScripting/Nodes/DataModel/Screens/DataModelEventNodeCustomView.axaml.cs +++ b/src/Artemis.VisualScripting/Nodes/DataModel/Screens/DataModelEventNodeCustomView.axaml.cs @@ -3,15 +3,11 @@ using Avalonia.ReactiveUI; namespace Artemis.VisualScripting.Nodes.DataModel.Screens; -public class DataModelEventNodeCustomView : ReactiveUserControl +public partial class DataModelEventNodeCustomView : ReactiveUserControl { public DataModelEventNodeCustomView() { InitializeComponent(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } } \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/DataModel/Screens/DataModelNodeCustomView.axaml.cs b/src/Artemis.VisualScripting/Nodes/DataModel/Screens/DataModelNodeCustomView.axaml.cs index 9be092730..c40e8768d 100644 --- a/src/Artemis.VisualScripting/Nodes/DataModel/Screens/DataModelNodeCustomView.axaml.cs +++ b/src/Artemis.VisualScripting/Nodes/DataModel/Screens/DataModelNodeCustomView.axaml.cs @@ -3,15 +3,11 @@ using Avalonia.ReactiveUI; namespace Artemis.VisualScripting.Nodes.DataModel.Screens; -public class DataModelNodeCustomView : ReactiveUserControl +public partial class DataModelNodeCustomView : ReactiveUserControl { public DataModelNodeCustomView() { InitializeComponent(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } } \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/External/Screens/LayerPropertyNodeCustomView.axaml.cs b/src/Artemis.VisualScripting/Nodes/External/Screens/LayerPropertyNodeCustomView.axaml.cs index 5f4996c3a..4348da66e 100644 --- a/src/Artemis.VisualScripting/Nodes/External/Screens/LayerPropertyNodeCustomView.axaml.cs +++ b/src/Artemis.VisualScripting/Nodes/External/Screens/LayerPropertyNodeCustomView.axaml.cs @@ -3,15 +3,11 @@ using Avalonia.ReactiveUI; namespace Artemis.VisualScripting.Nodes.External.Screens; -public class LayerPropertyNodeCustomView : ReactiveUserControl +public partial class LayerPropertyNodeCustomView : ReactiveUserControl { public LayerPropertyNodeCustomView() { InitializeComponent(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } } \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/External/Screens/LayerPropertyNodeCustomViewModel.cs b/src/Artemis.VisualScripting/Nodes/External/Screens/LayerPropertyNodeCustomViewModel.cs index c9cb56289..bca028ff6 100644 --- a/src/Artemis.VisualScripting/Nodes/External/Screens/LayerPropertyNodeCustomViewModel.cs +++ b/src/Artemis.VisualScripting/Nodes/External/Screens/LayerPropertyNodeCustomViewModel.cs @@ -1,10 +1,10 @@ using System.Collections.ObjectModel; +using System.Reactive.Disposables; using System.Reactive.Linq; using Artemis.Core; using Artemis.UI.Shared.Services.NodeEditor; using Artemis.UI.Shared.VisualScripting; using Artemis.VisualScripting.Nodes.External.Commands; -using Avalonia.Controls.Mixins; using DynamicData; using ReactiveUI; diff --git a/src/Artemis.VisualScripting/Nodes/Input/Screens/HotkeyEnableDisableNodeCustomView.axaml.cs b/src/Artemis.VisualScripting/Nodes/Input/Screens/HotkeyEnableDisableNodeCustomView.axaml.cs index 90bf774e0..7bc6bf76d 100644 --- a/src/Artemis.VisualScripting/Nodes/Input/Screens/HotkeyEnableDisableNodeCustomView.axaml.cs +++ b/src/Artemis.VisualScripting/Nodes/Input/Screens/HotkeyEnableDisableNodeCustomView.axaml.cs @@ -1,6 +1,4 @@ using Artemis.UI.Shared; -using Avalonia; -using Avalonia.Controls; using Avalonia.Markup.Xaml; using Avalonia.ReactiveUI; @@ -13,10 +11,6 @@ public partial class HotkeyEnableDisableNodeCustomView : ReactiveUserControl +public partial class MathExpressionNodeCustomView : ReactiveUserControl { public MathExpressionNodeCustomView() { InitializeComponent(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } private void InputElement_OnLostFocus(object? sender, RoutedEventArgs e) { diff --git a/src/Artemis.VisualScripting/Nodes/Mathematics/Screens/MathExpressionNodeCustomViewModel.cs b/src/Artemis.VisualScripting/Nodes/Mathematics/Screens/MathExpressionNodeCustomViewModel.cs index 46c5c337b..4cd475a8d 100644 --- a/src/Artemis.VisualScripting/Nodes/Mathematics/Screens/MathExpressionNodeCustomViewModel.cs +++ b/src/Artemis.VisualScripting/Nodes/Mathematics/Screens/MathExpressionNodeCustomViewModel.cs @@ -1,10 +1,10 @@ -using System.Reactive.Linq; +using System.Reactive.Disposables; +using System.Reactive.Linq; using Artemis.Core; using Artemis.Core.Events; using Artemis.UI.Shared.Services.NodeEditor; using Artemis.UI.Shared.Services.NodeEditor.Commands; using Artemis.UI.Shared.VisualScripting; -using Avalonia.Controls.Mixins; using ReactiveUI; using ReactiveUI.Validation.Extensions; diff --git a/src/Artemis.VisualScripting/Nodes/Operators/Screens/EnumEqualsNodeCustomView.axaml b/src/Artemis.VisualScripting/Nodes/Operators/Screens/EnumEqualsNodeCustomView.axaml index 0b19e7bd5..b97440803 100644 --- a/src/Artemis.VisualScripting/Nodes/Operators/Screens/EnumEqualsNodeCustomView.axaml +++ b/src/Artemis.VisualScripting/Nodes/Operators/Screens/EnumEqualsNodeCustomView.axaml @@ -7,7 +7,6 @@ diff --git a/src/Artemis.VisualScripting/Nodes/Operators/Screens/EnumEqualsNodeCustomView.axaml.cs b/src/Artemis.VisualScripting/Nodes/Operators/Screens/EnumEqualsNodeCustomView.axaml.cs index 0252616f0..88795dc01 100644 --- a/src/Artemis.VisualScripting/Nodes/Operators/Screens/EnumEqualsNodeCustomView.axaml.cs +++ b/src/Artemis.VisualScripting/Nodes/Operators/Screens/EnumEqualsNodeCustomView.axaml.cs @@ -3,15 +3,11 @@ using Avalonia.ReactiveUI; namespace Artemis.VisualScripting.Nodes.Operators.Screens; -public class EnumEqualsNodeCustomView : ReactiveUserControl +public partial class EnumEqualsNodeCustomView : ReactiveUserControl { public EnumEqualsNodeCustomView() { InitializeComponent(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } } \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Operators/Screens/EnumEqualsNodeCustomViewModel.cs b/src/Artemis.VisualScripting/Nodes/Operators/Screens/EnumEqualsNodeCustomViewModel.cs index dfff67695..7fee56fa6 100644 --- a/src/Artemis.VisualScripting/Nodes/Operators/Screens/EnumEqualsNodeCustomViewModel.cs +++ b/src/Artemis.VisualScripting/Nodes/Operators/Screens/EnumEqualsNodeCustomViewModel.cs @@ -1,11 +1,11 @@ using System.Collections.ObjectModel; +using System.Reactive.Disposables; using System.Reactive.Linq; using Artemis.Core; using Artemis.Core.Events; using Artemis.UI.Shared.Services.NodeEditor; using Artemis.UI.Shared.Services.NodeEditor.Commands; using Artemis.UI.Shared.VisualScripting; -using Avalonia.Controls.Mixins; using Avalonia.Threading; using DynamicData; using Humanizer; diff --git a/src/Artemis.VisualScripting/Nodes/Static/Screens/DisplayValueNodeCustomView.axaml b/src/Artemis.VisualScripting/Nodes/Static/Screens/DisplayValueNodeCustomView.axaml index 100dd461b..de10ffaa4 100644 --- a/src/Artemis.VisualScripting/Nodes/Static/Screens/DisplayValueNodeCustomView.axaml +++ b/src/Artemis.VisualScripting/Nodes/Static/Screens/DisplayValueNodeCustomView.axaml @@ -7,12 +7,15 @@ xmlns:core="clr-namespace:Artemis.Core;assembly=Artemis.Core" xmlns:converters1="clr-namespace:Artemis.UI.Shared.Converters;assembly=Artemis.UI.Shared" xmlns:collections="clr-namespace:System.Collections;assembly=System.Runtime" + xmlns:system="clr-namespace:System;assembly=System.Runtime" + xmlns:converters="clr-namespace:Artemis.VisualScripting.Converters" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" x:Class="Artemis.VisualScripting.Nodes.Static.Screens.DisplayValueNodeCustomView" x:DataType="screens:DisplayValueNodeCustomViewModel"> + @@ -41,14 +44,10 @@ - - - - - - - - + + + + diff --git a/src/Artemis.VisualScripting/Nodes/Static/Screens/DisplayValueNodeCustomView.axaml.cs b/src/Artemis.VisualScripting/Nodes/Static/Screens/DisplayValueNodeCustomView.axaml.cs index 9a448c403..769c49881 100644 --- a/src/Artemis.VisualScripting/Nodes/Static/Screens/DisplayValueNodeCustomView.axaml.cs +++ b/src/Artemis.VisualScripting/Nodes/Static/Screens/DisplayValueNodeCustomView.axaml.cs @@ -3,15 +3,11 @@ using Avalonia.ReactiveUI; namespace Artemis.VisualScripting.Nodes.Static.Screens; -public class DisplayValueNodeCustomView : ReactiveUserControl +public partial class DisplayValueNodeCustomView : ReactiveUserControl { public DisplayValueNodeCustomView() { InitializeComponent(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } } \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Static/Screens/StaticBooleanValueNodeCustomView.axaml.cs b/src/Artemis.VisualScripting/Nodes/Static/Screens/StaticBooleanValueNodeCustomView.axaml.cs index 6d619c059..c7a81e188 100644 --- a/src/Artemis.VisualScripting/Nodes/Static/Screens/StaticBooleanValueNodeCustomView.axaml.cs +++ b/src/Artemis.VisualScripting/Nodes/Static/Screens/StaticBooleanValueNodeCustomView.axaml.cs @@ -10,8 +10,4 @@ public partial class StaticBooleanValueNodeCustomView : ReactiveUserControl +public partial class StaticNumericValueNodeCustomView : ReactiveUserControl { public StaticNumericValueNodeCustomView() { InitializeComponent(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } } \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Static/Screens/StaticSKColorValueNodeCustomView.axaml.cs b/src/Artemis.VisualScripting/Nodes/Static/Screens/StaticSKColorValueNodeCustomView.axaml.cs index 285069694..51f401ac5 100644 --- a/src/Artemis.VisualScripting/Nodes/Static/Screens/StaticSKColorValueNodeCustomView.axaml.cs +++ b/src/Artemis.VisualScripting/Nodes/Static/Screens/StaticSKColorValueNodeCustomView.axaml.cs @@ -4,17 +4,13 @@ using FluentAvalonia.UI.Controls; namespace Artemis.VisualScripting.Nodes.Static.Screens; -public class StaticSKColorValueNodeCustomView : ReactiveUserControl +public partial class StaticSKColorValueNodeCustomView : ReactiveUserControl { public StaticSKColorValueNodeCustomView() { InitializeComponent(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } private void ColorPickerButton_OnFlyoutOpened(ColorPickerButton sender, EventArgs args) { diff --git a/src/Artemis.VisualScripting/Nodes/Static/Screens/StaticStringValueNodeCustomView.axaml.cs b/src/Artemis.VisualScripting/Nodes/Static/Screens/StaticStringValueNodeCustomView.axaml.cs index 427382854..95644633d 100644 --- a/src/Artemis.VisualScripting/Nodes/Static/Screens/StaticStringValueNodeCustomView.axaml.cs +++ b/src/Artemis.VisualScripting/Nodes/Static/Screens/StaticStringValueNodeCustomView.axaml.cs @@ -3,15 +3,11 @@ using Avalonia.ReactiveUI; namespace Artemis.VisualScripting.Nodes.Static.Screens; -public class StaticStringValueNodeCustomView : ReactiveUserControl +public partial class StaticStringValueNodeCustomView : ReactiveUserControl { public StaticStringValueNodeCustomView() { InitializeComponent(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } } \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Transition/Screens/EasingFunctionNodeCustomView.axaml.cs b/src/Artemis.VisualScripting/Nodes/Transition/Screens/EasingFunctionNodeCustomView.axaml.cs index 9af92d995..e989a374a 100644 --- a/src/Artemis.VisualScripting/Nodes/Transition/Screens/EasingFunctionNodeCustomView.axaml.cs +++ b/src/Artemis.VisualScripting/Nodes/Transition/Screens/EasingFunctionNodeCustomView.axaml.cs @@ -3,15 +3,11 @@ using Avalonia.ReactiveUI; namespace Artemis.VisualScripting.Nodes.Transition.Screens; -public class EasingFunctionNodeCustomView : ReactiveUserControl +public partial class EasingFunctionNodeCustomView : ReactiveUserControl { public EasingFunctionNodeCustomView() { InitializeComponent(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } } \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Transition/Screens/EasingFunctionView.axaml.cs b/src/Artemis.VisualScripting/Nodes/Transition/Screens/EasingFunctionView.axaml.cs index 3ff2acb0a..c55200ad6 100644 --- a/src/Artemis.VisualScripting/Nodes/Transition/Screens/EasingFunctionView.axaml.cs +++ b/src/Artemis.VisualScripting/Nodes/Transition/Screens/EasingFunctionView.axaml.cs @@ -3,15 +3,11 @@ using Avalonia.Markup.Xaml; namespace Artemis.VisualScripting.Nodes.Transition.Screens; -public class EasingFunctionView : UserControl +public partial class EasingFunctionView : UserControl { public EasingFunctionView() { InitializeComponent(); } - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } } \ No newline at end of file diff --git a/src/Artemis.WebClient.Updating/Artemis.WebClient.Updating.csproj b/src/Artemis.WebClient.Updating/Artemis.WebClient.Updating.csproj index f087e1de1..3492a7f04 100644 --- a/src/Artemis.WebClient.Updating/Artemis.WebClient.Updating.csproj +++ b/src/Artemis.WebClient.Updating/Artemis.WebClient.Updating.csproj @@ -1,15 +1,16 @@ - net6.0 + net7.0 enable enable - + + - + diff --git a/src/Artemis.WebClient.Updating/Queries/GetReleases.graphql b/src/Artemis.WebClient.Updating/Queries/GetReleases.graphql index 0297b3f39..ac56e6e3a 100644 --- a/src/Artemis.WebClient.Updating/Queries/GetReleases.graphql +++ b/src/Artemis.WebClient.Updating/Queries/GetReleases.graphql @@ -12,7 +12,7 @@ query GetReleases($branch: String!, $platform: Platform!, $take: Int!, $after: S pageInfo { hasNextPage endCursor - } + } nodes { id version