mirror of
https://github.com/godotengine/godot.git
synced 2024-11-24 05:04:10 +00:00
Implement [ExportToolButton]
This commit is contained in:
parent
db66bd35af
commit
4f52c2bb1f
@ -74,4 +74,31 @@ public class ExportDiagnosticsTests
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async void ExportToolButtonInNonToolClass()
|
||||
{
|
||||
await CSharpSourceGeneratorVerifier<ScriptPropertiesGenerator>.Verify(
|
||||
new string[] { "ExportDiagnostics_GD0108.cs" },
|
||||
new string[] { "ExportDiagnostics_GD0108_ScriptProperties.generated.cs" }
|
||||
);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async void ExportAndExportToolButtonOnSameMember()
|
||||
{
|
||||
await CSharpSourceGeneratorVerifier<ScriptPropertiesGenerator>.Verify(
|
||||
new string[] { "ExportDiagnostics_GD0109.cs" },
|
||||
new string[] { "ExportDiagnostics_GD0109_ScriptProperties.generated.cs" }
|
||||
);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async void ExportToolButtonOnNonCallable()
|
||||
{
|
||||
await CSharpSourceGeneratorVerifier<ScriptPropertiesGenerator>.Verify(
|
||||
new string[] { "ExportDiagnostics_GD0110.cs" },
|
||||
new string[] { "ExportDiagnostics_GD0110_ScriptProperties.generated.cs" }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -66,4 +66,13 @@ public class ScriptPropertiesGeneratorTests
|
||||
"AbstractGenericNode(Of T)_ScriptProperties.generated.cs"
|
||||
);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async void ExportedButtons()
|
||||
{
|
||||
await CSharpSourceGeneratorVerifier<ScriptPropertiesGenerator>.Verify(
|
||||
"ExportedToolButtons.cs",
|
||||
"ExportedToolButtons_ScriptProperties.generated.cs"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,48 @@
|
||||
using Godot;
|
||||
using Godot.NativeInterop;
|
||||
|
||||
partial class ExportDiagnostics_GD0108
|
||||
{
|
||||
#pragma warning disable CS0109 // Disable warning about redundant 'new' keyword
|
||||
/// <summary>
|
||||
/// Cached StringNames for the properties and fields contained in this class, for fast lookup.
|
||||
/// </summary>
|
||||
public new class PropertyName : global::Godot.Node.PropertyName {
|
||||
/// <summary>
|
||||
/// Cached name for the 'MyButton' field.
|
||||
/// </summary>
|
||||
public new static readonly global::Godot.StringName @MyButton = "MyButton";
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
|
||||
protected override bool SetGodotClassPropertyValue(in godot_string_name name, in godot_variant value)
|
||||
{
|
||||
if (name == PropertyName.@MyButton) {
|
||||
this.@MyButton = global::Godot.NativeInterop.VariantUtils.ConvertTo<global::Godot.Callable>(value);
|
||||
return true;
|
||||
}
|
||||
return base.SetGodotClassPropertyValue(name, value);
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
|
||||
protected override bool GetGodotClassPropertyValue(in godot_string_name name, out godot_variant value)
|
||||
{
|
||||
if (name == PropertyName.@MyButton) {
|
||||
value = global::Godot.NativeInterop.VariantUtils.CreateFrom<global::Godot.Callable>(this.@MyButton);
|
||||
return true;
|
||||
}
|
||||
return base.GetGodotClassPropertyValue(name, out value);
|
||||
}
|
||||
/// <summary>
|
||||
/// Get the property information for all the properties declared in this class.
|
||||
/// This method is used by Godot to register the available properties in the editor.
|
||||
/// Do not call this method.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
|
||||
internal new static global::System.Collections.Generic.List<global::Godot.Bridge.PropertyInfo> GetGodotPropertyList()
|
||||
{
|
||||
var properties = new global::System.Collections.Generic.List<global::Godot.Bridge.PropertyInfo>();
|
||||
return properties;
|
||||
}
|
||||
#pragma warning restore CS0109
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
using Godot;
|
||||
using Godot.NativeInterop;
|
||||
|
||||
partial class ExportDiagnostics_GD0109
|
||||
{
|
||||
#pragma warning disable CS0109 // Disable warning about redundant 'new' keyword
|
||||
/// <summary>
|
||||
/// Cached StringNames for the properties and fields contained in this class, for fast lookup.
|
||||
/// </summary>
|
||||
public new class PropertyName : global::Godot.Node.PropertyName {
|
||||
/// <summary>
|
||||
/// Cached name for the 'MyButton' field.
|
||||
/// </summary>
|
||||
public new static readonly global::Godot.StringName @MyButton = "MyButton";
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
|
||||
protected override bool SetGodotClassPropertyValue(in godot_string_name name, in godot_variant value)
|
||||
{
|
||||
if (name == PropertyName.@MyButton) {
|
||||
this.@MyButton = global::Godot.NativeInterop.VariantUtils.ConvertTo<global::Godot.Callable>(value);
|
||||
return true;
|
||||
}
|
||||
return base.SetGodotClassPropertyValue(name, value);
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
|
||||
protected override bool GetGodotClassPropertyValue(in godot_string_name name, out godot_variant value)
|
||||
{
|
||||
if (name == PropertyName.@MyButton) {
|
||||
value = global::Godot.NativeInterop.VariantUtils.CreateFrom<global::Godot.Callable>(this.@MyButton);
|
||||
return true;
|
||||
}
|
||||
return base.GetGodotClassPropertyValue(name, out value);
|
||||
}
|
||||
/// <summary>
|
||||
/// Get the property information for all the properties declared in this class.
|
||||
/// This method is used by Godot to register the available properties in the editor.
|
||||
/// Do not call this method.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
|
||||
internal new static global::System.Collections.Generic.List<global::Godot.Bridge.PropertyInfo> GetGodotPropertyList()
|
||||
{
|
||||
var properties = new global::System.Collections.Generic.List<global::Godot.Bridge.PropertyInfo>();
|
||||
return properties;
|
||||
}
|
||||
#pragma warning restore CS0109
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
using Godot;
|
||||
using Godot.NativeInterop;
|
||||
|
||||
partial class ExportDiagnostics_GD0110
|
||||
{
|
||||
#pragma warning disable CS0109 // Disable warning about redundant 'new' keyword
|
||||
/// <summary>
|
||||
/// Cached StringNames for the properties and fields contained in this class, for fast lookup.
|
||||
/// </summary>
|
||||
public new class PropertyName : global::Godot.Node.PropertyName {
|
||||
/// <summary>
|
||||
/// Cached name for the 'MyButton' field.
|
||||
/// </summary>
|
||||
public new static readonly global::Godot.StringName @MyButton = "MyButton";
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
|
||||
protected override bool SetGodotClassPropertyValue(in godot_string_name name, in godot_variant value)
|
||||
{
|
||||
if (name == PropertyName.@MyButton) {
|
||||
this.@MyButton = global::Godot.NativeInterop.VariantUtils.ConvertTo<string>(value);
|
||||
return true;
|
||||
}
|
||||
return base.SetGodotClassPropertyValue(name, value);
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
|
||||
protected override bool GetGodotClassPropertyValue(in godot_string_name name, out godot_variant value)
|
||||
{
|
||||
if (name == PropertyName.@MyButton) {
|
||||
value = global::Godot.NativeInterop.VariantUtils.CreateFrom<string>(this.@MyButton);
|
||||
return true;
|
||||
}
|
||||
return base.GetGodotClassPropertyValue(name, out value);
|
||||
}
|
||||
/// <summary>
|
||||
/// Get the property information for all the properties declared in this class.
|
||||
/// This method is used by Godot to register the available properties in the editor.
|
||||
/// Do not call this method.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
|
||||
internal new static global::System.Collections.Generic.List<global::Godot.Bridge.PropertyInfo> GetGodotPropertyList()
|
||||
{
|
||||
var properties = new global::System.Collections.Generic.List<global::Godot.Bridge.PropertyInfo>();
|
||||
return properties;
|
||||
}
|
||||
#pragma warning restore CS0109
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
using Godot;
|
||||
using Godot.NativeInterop;
|
||||
|
||||
partial class ExportedToolButtons
|
||||
{
|
||||
#pragma warning disable CS0109 // Disable warning about redundant 'new' keyword
|
||||
/// <summary>
|
||||
/// Cached StringNames for the properties and fields contained in this class, for fast lookup.
|
||||
/// </summary>
|
||||
public new class PropertyName : global::Godot.GodotObject.PropertyName {
|
||||
/// <summary>
|
||||
/// Cached name for the 'MyButton1' property.
|
||||
/// </summary>
|
||||
public new static readonly global::Godot.StringName @MyButton1 = "MyButton1";
|
||||
/// <summary>
|
||||
/// Cached name for the 'MyButton2' property.
|
||||
/// </summary>
|
||||
public new static readonly global::Godot.StringName @MyButton2 = "MyButton2";
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
|
||||
protected override bool GetGodotClassPropertyValue(in godot_string_name name, out godot_variant value)
|
||||
{
|
||||
if (name == PropertyName.@MyButton1) {
|
||||
value = global::Godot.NativeInterop.VariantUtils.CreateFrom<global::Godot.Callable>(this.@MyButton1);
|
||||
return true;
|
||||
}
|
||||
if (name == PropertyName.@MyButton2) {
|
||||
value = global::Godot.NativeInterop.VariantUtils.CreateFrom<global::Godot.Callable>(this.@MyButton2);
|
||||
return true;
|
||||
}
|
||||
return base.GetGodotClassPropertyValue(name, out value);
|
||||
}
|
||||
/// <summary>
|
||||
/// Get the property information for all the properties declared in this class.
|
||||
/// This method is used by Godot to register the available properties in the editor.
|
||||
/// Do not call this method.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
|
||||
internal new static global::System.Collections.Generic.List<global::Godot.Bridge.PropertyInfo> GetGodotPropertyList()
|
||||
{
|
||||
var properties = new global::System.Collections.Generic.List<global::Godot.Bridge.PropertyInfo>();
|
||||
properties.Add(new(type: (global::Godot.Variant.Type)25, name: PropertyName.@MyButton1, hint: (global::Godot.PropertyHint)39, hintString: "Click me!", usage: (global::Godot.PropertyUsageFlags)4, exported: true));
|
||||
properties.Add(new(type: (global::Godot.Variant.Type)25, name: PropertyName.@MyButton2, hint: (global::Godot.PropertyHint)39, hintString: "Click me!,ColorRect", usage: (global::Godot.PropertyUsageFlags)4, exported: true));
|
||||
return properties;
|
||||
}
|
||||
#pragma warning restore CS0109
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
using Godot;
|
||||
using Godot.Collections;
|
||||
|
||||
public partial class ExportDiagnostics_GD0108 : Node
|
||||
{
|
||||
[ExportToolButton("")]
|
||||
public Callable {|GD0108:MyButton|};
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
using Godot;
|
||||
using Godot.Collections;
|
||||
|
||||
[Tool]
|
||||
public partial class ExportDiagnostics_GD0109 : Node
|
||||
{
|
||||
[Export, ExportToolButton("")]
|
||||
public Callable {|GD0109:MyButton|};
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
using Godot;
|
||||
using Godot.Collections;
|
||||
|
||||
[Tool]
|
||||
public partial class ExportDiagnostics_GD0110 : Node
|
||||
{
|
||||
[ExportToolButton("")]
|
||||
public string {|GD0110:MyButton|};
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
using Godot;
|
||||
using System;
|
||||
|
||||
[Tool]
|
||||
public partial class ExportedToolButtons : GodotObject
|
||||
{
|
||||
[ExportToolButton("Click me!")]
|
||||
public Callable MyButton1 => Callable.From(() => { GD.Print("Clicked MyButton1!"); });
|
||||
|
||||
[ExportToolButton("Click me!", Icon = "ColorRect")]
|
||||
public Callable MyButton2 => Callable.From(() => { GD.Print("Clicked MyButton2!"); });
|
||||
}
|
@ -3,3 +3,6 @@
|
||||
Rule ID | Category | Severity | Notes
|
||||
--------|----------|----------|--------------------
|
||||
GD0003 | Usage | Error | ScriptPathAttributeGenerator, [Documentation](https://docs.godotengine.org/en/latest/tutorials/scripting/c_sharp/diagnostics/GD0003.html)
|
||||
GD0108 | Usage | Error | ScriptPropertiesGenerator, [Documentation](https://docs.godotengine.org/en/latest/tutorials/scripting/c_sharp/diagnostics/GD0108.html)
|
||||
GD0109 | Usage | Error | ScriptPropertiesGenerator, [Documentation](https://docs.godotengine.org/en/latest/tutorials/scripting/c_sharp/diagnostics/GD0109.html)
|
||||
GD0110 | Usage | Error | ScriptPropertiesGenerator, [Documentation](https://docs.godotengine.org/en/latest/tutorials/scripting/c_sharp/diagnostics/GD0110.html)
|
||||
|
@ -107,6 +107,36 @@ namespace Godot.SourceGenerators
|
||||
"Types not derived from Node should not export Node members. Node export is only supported in Node-derived classes.",
|
||||
helpLinkUri: string.Format(_helpLinkFormat, "GD0107"));
|
||||
|
||||
public static readonly DiagnosticDescriptor OnlyToolClassesShouldUseExportToolButtonRule =
|
||||
new DiagnosticDescriptor(id: "GD0108",
|
||||
title: "The exported tool button is not in a tool class",
|
||||
messageFormat: "The exported tool button '{0}' is not in a tool class",
|
||||
category: "Usage",
|
||||
DiagnosticSeverity.Error,
|
||||
isEnabledByDefault: true,
|
||||
"The exported tool button is not in a tool class. Annotate the class with the '[Tool]' attribute, or remove the '[ExportToolButton]' attribute.",
|
||||
helpLinkUri: string.Format(_helpLinkFormat, "GD0108"));
|
||||
|
||||
public static readonly DiagnosticDescriptor ExportToolButtonShouldNotBeUsedWithExportRule =
|
||||
new DiagnosticDescriptor(id: "GD0109",
|
||||
title: "The '[ExportToolButton]' attribute cannot be used with another '[Export]' attribute",
|
||||
messageFormat: "The '[ExportToolButton]' attribute cannot be used with another '[Export]' attribute on '{0}'",
|
||||
category: "Usage",
|
||||
DiagnosticSeverity.Error,
|
||||
isEnabledByDefault: true,
|
||||
"The '[ExportToolButton]' attribute cannot be used with the '[Export]' attribute. Remove one of the attributes.",
|
||||
helpLinkUri: string.Format(_helpLinkFormat, "GD0109"));
|
||||
|
||||
public static readonly DiagnosticDescriptor ExportToolButtonIsNotCallableRule =
|
||||
new DiagnosticDescriptor(id: "GD0110",
|
||||
title: "The exported tool button is not a Callable",
|
||||
messageFormat: "The exported tool button '{0}' is not a Callable",
|
||||
category: "Usage",
|
||||
DiagnosticSeverity.Error,
|
||||
isEnabledByDefault: true,
|
||||
"The exported tool button is not a Callable. The '[ExportToolButton]' attribute is only supported on members of type Callable.",
|
||||
helpLinkUri: string.Format(_helpLinkFormat, "GD0110"));
|
||||
|
||||
public static readonly DiagnosticDescriptor SignalDelegateMissingSuffixRule =
|
||||
new DiagnosticDescriptor(id: "GD0201",
|
||||
title: "The name of the delegate must end with 'EventHandler'",
|
||||
|
@ -287,6 +287,12 @@ namespace Godot.SourceGenerators
|
||||
public static bool IsGodotGlobalClassAttribute(this INamedTypeSymbol symbol)
|
||||
=> symbol.FullQualifiedNameOmitGlobal() == GodotClasses.GlobalClassAttr;
|
||||
|
||||
public static bool IsGodotExportToolButtonAttribute(this INamedTypeSymbol symbol)
|
||||
=> symbol.FullQualifiedNameOmitGlobal() == GodotClasses.ExportToolButtonAttr;
|
||||
|
||||
public static bool IsGodotToolAttribute(this INamedTypeSymbol symbol)
|
||||
=> symbol.FullQualifiedNameOmitGlobal() == GodotClasses.ToolAttr;
|
||||
|
||||
public static bool IsSystemFlagsAttribute(this INamedTypeSymbol symbol)
|
||||
=> symbol.FullQualifiedNameOmitGlobal() == GodotClasses.SystemFlagsAttr;
|
||||
|
||||
|
@ -9,10 +9,12 @@ namespace Godot.SourceGenerators
|
||||
public const string ExportCategoryAttr = "Godot.ExportCategoryAttribute";
|
||||
public const string ExportGroupAttr = "Godot.ExportGroupAttribute";
|
||||
public const string ExportSubgroupAttr = "Godot.ExportSubgroupAttribute";
|
||||
public const string ExportToolButtonAttr = "Godot.ExportToolButtonAttribute";
|
||||
public const string SignalAttr = "Godot.SignalAttribute";
|
||||
public const string MustBeVariantAttr = "Godot.MustBeVariantAttribute";
|
||||
public const string GodotClassNameAttr = "Godot.GodotClassNameAttribute";
|
||||
public const string GlobalClassAttr = "Godot.GlobalClassAttribute";
|
||||
public const string ToolAttr = "Godot.ToolAttribute";
|
||||
public const string SystemFlagsAttr = "System.FlagsAttribute";
|
||||
}
|
||||
}
|
||||
|
@ -89,7 +89,8 @@ namespace Godot.SourceGenerators
|
||||
Password = 36,
|
||||
LayersAvoidance = 37,
|
||||
DictionaryType = 38,
|
||||
Max = 39
|
||||
ToolButton = 39,
|
||||
Max = 40
|
||||
}
|
||||
|
||||
[Flags]
|
||||
|
@ -69,6 +69,7 @@ namespace Godot.SourceGenerators
|
||||
bool hasNamespace = classNs.Length != 0;
|
||||
|
||||
bool isInnerClass = symbol.ContainingType != null;
|
||||
bool isToolClass = symbol.GetAttributes().Any(a => a.AttributeClass?.IsGodotToolAttribute() ?? false);
|
||||
|
||||
string uniqueHint = symbol.FullQualifiedNameOmitGlobal().SanitizeQualifiedNameForUniqueHint()
|
||||
+ "_ScriptProperties.generated";
|
||||
@ -277,6 +278,16 @@ namespace Godot.SourceGenerators
|
||||
if (propertyInfo == null)
|
||||
continue;
|
||||
|
||||
if (propertyInfo.Value.Hint == PropertyHint.ToolButton && !isToolClass)
|
||||
{
|
||||
context.ReportDiagnostic(Diagnostic.Create(
|
||||
Common.OnlyToolClassesShouldUseExportToolButtonRule,
|
||||
member.Symbol.Locations.FirstLocationWithSourceTreeOrDefault(),
|
||||
member.Symbol.ToDisplayString()
|
||||
));
|
||||
continue;
|
||||
}
|
||||
|
||||
AppendPropertyInfo(source, propertyInfo.Value);
|
||||
}
|
||||
|
||||
@ -418,6 +429,19 @@ namespace Godot.SourceGenerators
|
||||
var exportAttr = memberSymbol.GetAttributes()
|
||||
.FirstOrDefault(a => a.AttributeClass?.IsGodotExportAttribute() ?? false);
|
||||
|
||||
var exportToolButtonAttr = memberSymbol.GetAttributes()
|
||||
.FirstOrDefault(a => a.AttributeClass?.IsGodotExportToolButtonAttribute() ?? false);
|
||||
|
||||
if (exportAttr != null && exportToolButtonAttr != null)
|
||||
{
|
||||
context.ReportDiagnostic(Diagnostic.Create(
|
||||
Common.ExportToolButtonShouldNotBeUsedWithExportRule,
|
||||
memberSymbol.Locations.FirstLocationWithSourceTreeOrDefault(),
|
||||
memberSymbol.ToDisplayString()
|
||||
));
|
||||
return null;
|
||||
}
|
||||
|
||||
var propertySymbol = memberSymbol as IPropertySymbol;
|
||||
var fieldSymbol = memberSymbol as IFieldSymbol;
|
||||
|
||||
@ -446,19 +470,56 @@ namespace Godot.SourceGenerators
|
||||
}
|
||||
}
|
||||
|
||||
if (exportToolButtonAttr != null && propertySymbol != null && propertySymbol.GetMethod == null)
|
||||
{
|
||||
context.ReportDiagnostic(Diagnostic.Create(
|
||||
Common.ExportedPropertyIsWriteOnlyRule,
|
||||
propertySymbol.Locations.FirstLocationWithSourceTreeOrDefault(),
|
||||
propertySymbol.ToDisplayString()
|
||||
));
|
||||
return null;
|
||||
}
|
||||
|
||||
var memberType = propertySymbol?.Type ?? fieldSymbol!.Type;
|
||||
|
||||
var memberVariantType = MarshalUtils.ConvertMarshalTypeToVariantType(marshalType)!.Value;
|
||||
string memberName = memberSymbol.Name;
|
||||
|
||||
string? hintString = null;
|
||||
|
||||
if (exportToolButtonAttr != null)
|
||||
{
|
||||
if (memberVariantType != VariantType.Callable)
|
||||
{
|
||||
context.ReportDiagnostic(Diagnostic.Create(
|
||||
Common.ExportToolButtonIsNotCallableRule,
|
||||
memberSymbol.Locations.FirstLocationWithSourceTreeOrDefault(),
|
||||
memberSymbol.ToDisplayString()
|
||||
));
|
||||
return null;
|
||||
}
|
||||
|
||||
hintString = exportToolButtonAttr.ConstructorArguments[0].Value?.ToString() ?? "";
|
||||
foreach (var namedArgument in exportToolButtonAttr.NamedArguments)
|
||||
{
|
||||
if (namedArgument is { Key: "Icon", Value.Value: string { Length: > 0 } })
|
||||
{
|
||||
hintString += $",{namedArgument.Value.Value}";
|
||||
}
|
||||
}
|
||||
|
||||
return new PropertyInfo(memberVariantType, memberName, PropertyHint.ToolButton,
|
||||
hintString: hintString, PropertyUsageFlags.Editor, exported: true);
|
||||
}
|
||||
|
||||
if (exportAttr == null)
|
||||
{
|
||||
return new PropertyInfo(memberVariantType, memberName, PropertyHint.None,
|
||||
hintString: null, PropertyUsageFlags.ScriptVariable, exported: false);
|
||||
hintString: hintString, PropertyUsageFlags.ScriptVariable, exported: false);
|
||||
}
|
||||
|
||||
if (!TryGetMemberExportHint(typeCache, memberType, exportAttr, memberVariantType,
|
||||
isTypeArgument: false, out var hint, out var hintString))
|
||||
isTypeArgument: false, out var hint, out hintString))
|
||||
{
|
||||
var constructorArguments = exportAttr.ConstructorArguments;
|
||||
|
||||
|
@ -0,0 +1,33 @@
|
||||
using System;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Godot
|
||||
{
|
||||
/// <summary>
|
||||
/// Exports the annotated <see cref="Callable"/> as a clickable button.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
|
||||
public sealed class ExportToolButtonAttribute : Attribute
|
||||
{
|
||||
/// <summary>
|
||||
/// The label of the button.
|
||||
/// </summary>
|
||||
public string Text { get; }
|
||||
|
||||
/// <summary>
|
||||
/// If defined, used to fetch an icon for the button via <see cref="Control.GetThemeIcon"/>,
|
||||
/// from the <code>EditorIcons</code> theme type.
|
||||
/// </summary>
|
||||
public string? Icon { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Exports the annotated <see cref="Callable"/> as a clickable button.
|
||||
/// </summary>
|
||||
/// <param name="text">The label of the button.</param>
|
||||
public ExportToolButtonAttribute(string text)
|
||||
{
|
||||
Text = text;
|
||||
}
|
||||
}
|
||||
}
|
@ -48,6 +48,7 @@
|
||||
<!-- Sources -->
|
||||
<ItemGroup>
|
||||
<Compile Include="Core\Aabb.cs" />
|
||||
<Compile Include="Core\Attributes\ExportToolButtonAttribute.cs" />
|
||||
<Compile Include="Core\Bridge\GodotSerializationInfo.cs" />
|
||||
<Compile Include="Core\Bridge\MethodInfo.cs" />
|
||||
<Compile Include="Core\Callable.generics.cs" />
|
||||
|
Loading…
Reference in New Issue
Block a user