mirror of
https://github.com/godotengine/godot.git
synced 2025-11-01 06:01:14 +00:00
Allow exporting variables of type Variant
This commit is contained in:
parent
96cdbbe5bd
commit
012d47b089
5 changed files with 127 additions and 12 deletions
|
|
@ -57,7 +57,7 @@
|
|||
#include "scene/resources/mesh.h"
|
||||
#include "scene/resources/visual_shader_nodes.h"
|
||||
|
||||
///////////////////// Nil /////////////////////////
|
||||
///////////////////// NIL /////////////////////////
|
||||
|
||||
void EditorPropertyNil::update_property() {
|
||||
}
|
||||
|
|
@ -68,6 +68,91 @@ EditorPropertyNil::EditorPropertyNil() {
|
|||
add_child(prop_label);
|
||||
}
|
||||
|
||||
//////////////////// VARIANT ///////////////////////
|
||||
|
||||
void EditorPropertyVariant::_change_type(int p_to_type) {
|
||||
new_type = Variant::Type(p_to_type);
|
||||
|
||||
Variant zero;
|
||||
Callable::CallError ce;
|
||||
Variant::construct(new_type, zero, nullptr, 0, ce);
|
||||
emit_changed(get_edited_property(), zero);
|
||||
}
|
||||
|
||||
void EditorPropertyVariant::_set_read_only(bool p_read_only) {
|
||||
change_type->set_disabled(p_read_only);
|
||||
if (sub_property) {
|
||||
sub_property->set_read_only(p_read_only);
|
||||
}
|
||||
}
|
||||
|
||||
void EditorPropertyVariant::_notification(int p_what) {
|
||||
if (p_what == NOTIFICATION_THEME_CHANGED) {
|
||||
change_type->set_button_icon(get_editor_theme_icon("Edit"));
|
||||
|
||||
PopupMenu *popup = change_type->get_popup();
|
||||
for (int i = 0; i < popup->get_item_count(); i++) {
|
||||
popup->set_item_icon(i, get_editor_theme_icon(Variant::get_type_name(Variant::Type(popup->get_item_id(i)))));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EditorPropertyVariant::update_property() {
|
||||
const Variant &value = get_edited_property_value();
|
||||
if (new_type == Variant::VARIANT_MAX) {
|
||||
new_type = value.get_type();
|
||||
}
|
||||
|
||||
if (new_type != current_type) {
|
||||
current_type = new_type;
|
||||
|
||||
if (sub_property) {
|
||||
memdelete(sub_property);
|
||||
sub_property = nullptr;
|
||||
}
|
||||
|
||||
if (current_type == Variant::OBJECT) {
|
||||
sub_property = EditorInspector::instantiate_property_editor(nullptr, current_type, "", PROPERTY_HINT_RESOURCE_TYPE, "Resource", PROPERTY_USAGE_NONE);
|
||||
} else {
|
||||
sub_property = EditorInspector::instantiate_property_editor(nullptr, current_type, "", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE);
|
||||
}
|
||||
ERR_FAIL_NULL(sub_property);
|
||||
|
||||
sub_property->set_object_and_property(get_edited_object(), get_edited_property());
|
||||
sub_property->set_name_split_ratio(0);
|
||||
sub_property->set_selectable(false);
|
||||
sub_property->set_use_folding(is_using_folding());
|
||||
sub_property->set_read_only(is_read_only());
|
||||
sub_property->set_h_size_flags(SIZE_EXPAND_FILL);
|
||||
sub_property->connect(SNAME("property_changed"), callable_mp((EditorProperty *)this, &EditorProperty::emit_changed));
|
||||
content->add_child(sub_property);
|
||||
content->move_child(sub_property, 0);
|
||||
sub_property->update_property();
|
||||
} else if (sub_property) {
|
||||
sub_property->update_property();
|
||||
}
|
||||
new_type = Variant::VARIANT_MAX;
|
||||
}
|
||||
|
||||
EditorPropertyVariant::EditorPropertyVariant() {
|
||||
content = memnew(HBoxContainer);
|
||||
add_child(content);
|
||||
|
||||
change_type = memnew(MenuButton);
|
||||
change_type->set_flat(false);
|
||||
|
||||
PopupMenu *popup = change_type->get_popup();
|
||||
for (int i = 0; i < Variant::VARIANT_MAX; i++) {
|
||||
if (i == Variant::CALLABLE || i == Variant::SIGNAL || i == Variant::RID) {
|
||||
// These types can't be constructed or serialized properly, so skip them.
|
||||
continue;
|
||||
}
|
||||
popup->add_item(Variant::get_type_name(Variant::Type(i)), i);
|
||||
}
|
||||
popup->connect(SceneStringName(id_pressed), callable_mp(this, &EditorPropertyVariant::_change_type));
|
||||
content->add_child(change_type);
|
||||
}
|
||||
|
||||
///////////////////// TEXT /////////////////////////
|
||||
|
||||
void EditorPropertyText::_set_read_only(bool p_read_only) {
|
||||
|
|
@ -3510,8 +3595,11 @@ EditorProperty *EditorInspectorDefaultPlugin::get_editor_for_property(Object *p_
|
|||
switch (p_type) {
|
||||
// atomic types
|
||||
case Variant::NIL: {
|
||||
EditorPropertyNil *editor = memnew(EditorPropertyNil);
|
||||
return editor;
|
||||
if (p_usage & PROPERTY_USAGE_NIL_IS_VARIANT) {
|
||||
return memnew(EditorPropertyVariant);
|
||||
} else {
|
||||
return memnew(EditorPropertyNil);
|
||||
}
|
||||
} break;
|
||||
case Variant::BOOL: {
|
||||
EditorPropertyCheck *editor = memnew(EditorPropertyCheck);
|
||||
|
|
|
|||
|
|
@ -55,6 +55,27 @@ public:
|
|||
EditorPropertyNil();
|
||||
};
|
||||
|
||||
class EditorPropertyVariant : public EditorProperty {
|
||||
GDCLASS(EditorPropertyVariant, EditorProperty);
|
||||
|
||||
HBoxContainer *content = nullptr;
|
||||
EditorProperty *sub_property = nullptr;
|
||||
MenuButton *change_type = nullptr;
|
||||
|
||||
Variant::Type current_type = Variant::VARIANT_MAX;
|
||||
Variant::Type new_type = Variant::VARIANT_MAX;
|
||||
|
||||
void _change_type(int p_to_type);
|
||||
|
||||
protected:
|
||||
virtual void _set_read_only(bool p_read_only) override;
|
||||
void _notification(int p_what);
|
||||
|
||||
public:
|
||||
virtual void update_property() override;
|
||||
EditorPropertyVariant();
|
||||
};
|
||||
|
||||
class EditorPropertyText : public EditorProperty {
|
||||
GDCLASS(EditorPropertyText, EditorProperty);
|
||||
LineEdit *text = nullptr;
|
||||
|
|
|
|||
|
|
@ -998,7 +998,7 @@ void TileSourceInspectorPlugin::_confirm_change_id() {
|
|||
}
|
||||
|
||||
bool TileSourceInspectorPlugin::can_handle(Object *p_object) {
|
||||
return p_object->is_class("TileSetAtlasSourceProxyObject") || p_object->is_class("TileSetScenesCollectionProxyObject");
|
||||
return p_object && (p_object->is_class("TileSetAtlasSourceProxyObject") || p_object->is_class("TileSetScenesCollectionProxyObject"));
|
||||
}
|
||||
|
||||
bool TileSourceInspectorPlugin::parse_property(Object *p_object, const Variant::Type p_type, const String &p_path, const PropertyHint p_hint, const String &p_hint_text, const BitField<PropertyUsageFlags> p_usage, const bool p_wide) {
|
||||
|
|
|
|||
|
|
@ -4533,15 +4533,10 @@ bool GDScriptParser::export_annotations(AnnotationNode *p_annotation, Node *p_ta
|
|||
return false;
|
||||
}
|
||||
|
||||
if (export_type.is_variant() || export_type.has_no_type()) {
|
||||
if (is_dict) {
|
||||
// Dictionary allowed to have a variant key/value.
|
||||
export_type.kind = GDScriptParser::DataType::BUILTIN;
|
||||
} else {
|
||||
if (export_type.has_no_type()) {
|
||||
push_error(R"(Cannot use simple "@export" annotation because the type of the initialized value can't be inferred.)", p_annotation);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
switch (export_type.kind) {
|
||||
case GDScriptParser::DataType::BUILTIN:
|
||||
|
|
@ -4591,6 +4586,12 @@ bool GDScriptParser::export_annotations(AnnotationNode *p_annotation, Node *p_ta
|
|||
variable->export_info.class_name = String(export_type.native_type).replace("::", ".");
|
||||
}
|
||||
} break;
|
||||
case GDScriptParser::DataType::VARIANT: {
|
||||
if (export_type.is_variant()) {
|
||||
variable->export_info.type = Variant::NIL;
|
||||
variable->export_info.usage |= PROPERTY_USAGE_NIL_IS_VARIANT;
|
||||
}
|
||||
} break;
|
||||
default:
|
||||
push_error(R"(Export type can only be built-in, a resource, a node, or an enum.)", p_annotation);
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -10,6 +10,11 @@ namespace GodotTools.Inspector
|
|||
{
|
||||
public override bool _CanHandle(GodotObject godotObject)
|
||||
{
|
||||
if (godotObject == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach (var script in EnumerateScripts(godotObject))
|
||||
{
|
||||
if (script is CSharpScript)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue