-
-
Notifications
You must be signed in to change notification settings - Fork 21.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Exported script properties and sub-resource scripts will now be properly treated as Scripts #30738
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2182,8 +2182,97 @@ void EditorPropertyResource::_menu_option(int p_which) { | |
} break; | ||
case OBJ_MENU_NEW_SCRIPT: { | ||
|
||
if (Object::cast_to<Node>(get_edited_object())) { | ||
if (Object::cast_to<Node>(get_edited_object()) && | ||
EditorNode::get_singleton()->get_editor_data().get_edited_scene_root()->is_a_parent_of(Object::cast_to<Node>(get_edited_object())) && | ||
get_edited_property() == "script") { | ||
// This is a script property of a node in the scene tree, so we should defer to the SceneTreeDock's script creation code | ||
EditorNode::get_singleton()->get_scene_tree_dock()->open_script_dialog(Object::cast_to<Node>(get_edited_object())); | ||
} else { | ||
|
||
// Based upon editor/scene_tree_dock.cpp#_tool_selected (case TOOL_ATTACH_SCRIPT); edited | ||
// to account for exported script properties, resources, and sub-resources | ||
|
||
Ref<Script> existing = get_edited_object()->get(get_edited_property()); | ||
|
||
String inherits; | ||
if (existing.is_valid()) { | ||
// A script already exists in this property, so inherit from that script | ||
for (int i = 0; i < ScriptServer::get_language_count(); i++) { | ||
ScriptLanguage *l = ScriptServer::get_language(i); | ||
if (l->get_type() == existing->get_class()) { | ||
String name = l->get_global_class_name(existing->get_path()); | ||
if (ScriptServer::is_global_class(name) && EDITOR_GET("interface/editors/derive_script_globals_by_name").operator bool()) { | ||
inherits = name; | ||
} else if (l->can_inherit_from_file()) { | ||
inherits = "\"" + existing->get_path() + "\""; | ||
} | ||
break; | ||
} | ||
} | ||
} else if (get_edited_property() == "script") { | ||
// This is the script property of an object's sub-property, so inherit from that object's class | ||
inherits = get_edited_object()->get_class(); | ||
} else { | ||
inherits = "Reference"; | ||
} | ||
|
||
String path; | ||
// Path creation: | ||
// Get the object's basename | ||
// If the object has no basename, get the scene root's filename | ||
// If the scene root has a filename, append the object's name/class to it | ||
// If it does not, append the object's name/class to "res://" | ||
// If the property we're editing is not "script", append the property name to the filename | ||
if (Object::cast_to<Node>(get_edited_object()) && | ||
EditorNode::get_singleton()->get_editor_data().get_edited_scene_root()->is_a_parent_of(Object::cast_to<Node>(get_edited_object()))) { | ||
// This is a node in the scene tree, but it is not the script property | ||
Node *edited_node = Object::cast_to<Node>(get_edited_object()); | ||
|
||
path = edited_node->get_filename().get_basename(); | ||
if (path == "") { | ||
String root_path = EditorNode::get_singleton()->get_editor_data().get_edited_scene_root()->get_filename(); | ||
if (root_path == "") { | ||
path = String("res://").plus_file(edited_node->get_name()); | ||
} else { | ||
path = root_path.get_base_dir().plus_file(edited_node->get_name()); | ||
} | ||
} | ||
} else if (Object::cast_to<Resource>(get_edited_object())) { | ||
RES edited_res = Object::cast_to<Resource>(get_edited_object()); | ||
|
||
path = edited_res->get_path().get_basename(); | ||
if (path == "") { | ||
String root_path = EditorNode::get_singleton()->get_editor_data().get_edited_scene_root()->get_filename(); | ||
if (root_path == "") { | ||
path = String("res://").plus_file(edited_res->get_name()); | ||
} else { | ||
path = root_path.get_base_dir().plus_file(edited_res->get_name()); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would it be more appropriate to put this section of code (as well as the copies for Node and the else statement) in a macro, for re-use in all three cases? I would normally just go ahead and do so, but I'm not sure if such a move would be appreciated (considering the only macros I ever see in the engine are the error macros), or if there is perhaps a better way of doing that. |
||
} | ||
} else { | ||
String root_path = EditorNode::get_singleton()->get_editor_data().get_edited_scene_root()->get_filename(); | ||
if (root_path == "") { | ||
path = String("res://").plus_file(get_edited_object()->get_class()); | ||
} else { | ||
path = root_path.get_base_dir().plus_file(get_edited_object()->get_class()); | ||
} | ||
} | ||
|
||
// If we're editing an object that isn't in the scene tree, we still have the script property, | ||
// so we don't want to accidentally add the property name to the end of the script path. | ||
if (get_edited_property() != "script") { | ||
// path = <node_or_scene_name>.<property_name>. | ||
// The extra period at the end is to prevent the property name from being seen as the type by ScriptCreateDialog | ||
String path_property_name = get_edited_property(); | ||
path_property_name = path_property_name.replace(":", ".").replace("/", ".").replace("\\", "."); | ||
path = path + "." + path_property_name + "."; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It would be nice if it could get a NodePath to the current property. For example, if the path to the property is |
||
} | ||
|
||
ScriptCreateDialog *script_create_dialog = EditorNode::get_singleton()->get_inspector()->get_script_create_dialog(); | ||
script_create_dialog->connect("script_created", this, "_script_created"); | ||
script_create_dialog->connect("popup_hide", this, "_script_creation_closed", varray(), CONNECT_ONESHOT); | ||
script_create_dialog->config(inherits, path); | ||
script_create_dialog->popup_centered(); | ||
} | ||
|
||
} break; | ||
|
@@ -2308,14 +2397,26 @@ void EditorPropertyResource::_resource_preview(const String &p_path, const Ref<T | |
} | ||
} | ||
|
||
void EditorPropertyResource::_script_created(Ref<Script> p_script) { | ||
|
||
// Based partially upon editor/scene_tree_dock.cpp#_script_created | ||
emit_changed(get_edited_property(), p_script); | ||
update_property(); | ||
} | ||
|
||
void EditorPropertyResource::_script_creation_closed() { | ||
ScriptCreateDialog *script_create_dialog = EditorNode::get_singleton()->get_inspector()->get_script_create_dialog(); | ||
script_create_dialog->disconnect("script_created", this, "_script_created"); | ||
} | ||
|
||
void EditorPropertyResource::_update_menu_items() { | ||
|
||
//////////////////// UPDATE MENU ////////////////////////// | ||
RES res = get_edited_object()->get(get_edited_property()); | ||
|
||
menu->clear(); | ||
|
||
if (get_edited_property() == "script" && base_type == "Script" && Object::cast_to<Node>(get_edited_object())) { | ||
if (base_type == "Script") { | ||
menu->add_icon_item(get_icon("Script", "EditorIcons"), TTR("New Script"), OBJ_MENU_NEW_SCRIPT); | ||
menu->add_separator(); | ||
} else if (base_type != "") { | ||
|
@@ -2833,6 +2934,8 @@ void EditorPropertyResource::_bind_methods() { | |
ClassDB::bind_method(D_METHOD("_resource_preview"), &EditorPropertyResource::_resource_preview); | ||
ClassDB::bind_method(D_METHOD("_resource_selected"), &EditorPropertyResource::_resource_selected); | ||
ClassDB::bind_method(D_METHOD("_viewport_selected"), &EditorPropertyResource::_viewport_selected); | ||
ClassDB::bind_method(D_METHOD("_script_created"), &EditorPropertyResource::_script_created); | ||
ClassDB::bind_method(D_METHOD("_script_creation_closed"), &EditorPropertyResource::_script_creation_closed); | ||
ClassDB::bind_method(D_METHOD("_sub_inspector_property_keyed"), &EditorPropertyResource::_sub_inspector_property_keyed); | ||
ClassDB::bind_method(D_METHOD("_sub_inspector_resource_selected"), &EditorPropertyResource::_sub_inspector_resource_selected); | ||
ClassDB::bind_method(D_METHOD("_sub_inspector_object_id_selected"), &EditorPropertyResource::_sub_inspector_object_id_selected); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would want to try to merge this again, but instead of merging it back into the mentioned function (as I tried with my first attempt), I would prefer to merge this and the above-mentioned function into
editor/editor_node.cpp
(or another editor class that's a bit more "global", if you get what I mean) in some manner.That said, the reason I have not done so already is that I don't think that's within the scope of this PR -- but if it can be considered within the scope, I might try my hand at it.