diff --git a/doc/classes/EditorPlugin.xml b/doc/classes/EditorPlugin.xml
index b9945f3f732..f5fbf8e313a 100644
--- a/doc/classes/EditorPlugin.xml
+++ b/doc/classes/EditorPlugin.xml
@@ -235,6 +235,13 @@
+
+
+
+
+ Gets the Editor's dialogue used for making scripts. Note that users can configure it before use.
+
+
diff --git a/doc/classes/ScriptCreateDialog.xml b/doc/classes/ScriptCreateDialog.xml
new file mode 100644
index 00000000000..f09d2820261
--- /dev/null
+++ b/doc/classes/ScriptCreateDialog.xml
@@ -0,0 +1,45 @@
+
+
+
+ The Editor's popup dialog for creating new [Script] files.
+
+
+ The ScriptCreateDialog creates script files according to a given template for a given scripting language. The standard use is to configure its fields prior to calling a [method popup]() method.
+ [codeblock]
+ func _ready():
+ dialog.config("Node", "res://new_node.gd") # for in-engine types
+ dialog.config("\"res://base_node.gd\"", "res://derived_node.gd") # for script types
+ dialog.popup_centered()
+ [/codeblock]
+
+
+
+
+
+
+
+
+
+
+ The dialog's "Inherits" field content.
+
+
+ The dialog's "Path" field content.
+
+
+ Prefills required fields to configure the ScriptCreateDialog for use.
+
+
+
+
+
+
+
+
+ Emitted when the user clicks the OK button.
+
+
+
+
+
+
diff --git a/editor/create_dialog.cpp b/editor/create_dialog.cpp
index 36978e37a58..a8cbf52cd23 100644
--- a/editor/create_dialog.cpp
+++ b/editor/create_dialog.cpp
@@ -262,13 +262,17 @@ void CreateDialog::_update_search() {
if (base_type == "Node" && type.begins_with("Editor"))
continue; // do not show editor nodes
- if (base_type == "Resource" && ClassDB::is_parent_class(type, "PluginScript"))
- // PluginScript must be initialized before use, which is not possible here
- continue;
-
if (!ClassDB::can_instance(type))
continue; // can't create what can't be instanced
+ bool skip = false;
+ for (Set::Element *E = type_blacklist.front(); E && !skip; E = E->next()) {
+ if (ClassDB::is_parent_class(type, E->get()))
+ skip = true;
+ }
+ if (skip)
+ continue;
+
if (search_box->get_text() == "") {
add_type(type, types, root, &to_select);
} else {
@@ -706,4 +710,7 @@ CreateDialog::CreateDialog() {
help_bit = memnew(EditorHelpBit);
vbc->add_margin_child(TTR("Description:"), help_bit);
help_bit->connect("request_hide", this, "_closed");
+
+ type_blacklist.insert("PluginScript"); // PluginScript must be initialized before use, which is not possible here
+ type_blacklist.insert("ScriptCreateDialog"); // This is an exposed editor Node that doesn't have an Editor prefix.
}
diff --git a/editor/create_dialog.h b/editor/create_dialog.h
index da17dcbe893..f8eec231a43 100644
--- a/editor/create_dialog.h
+++ b/editor/create_dialog.h
@@ -58,6 +58,7 @@ class CreateDialog : public ConfirmationDialog {
String preferred_search_result_type;
EditorHelpBit *help_bit;
List type_list;
+ Set type_blacklist;
void _item_selected();
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index f099f292048..5ab5a717adf 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -3075,6 +3075,7 @@ void EditorNode::register_editor_types() {
ClassDB::register_class();
ClassDB::register_class();
ClassDB::register_class();
+ ClassDB::register_class();
// FIXME: Is this stuff obsolete, or should it be ported to new APIs?
ClassDB::register_class();
@@ -4430,6 +4431,8 @@ void EditorNode::_bind_methods() {
ClassDB::bind_method("stop_child_process", &EditorNode::stop_child_process);
+ ClassDB::bind_method("get_script_create_dialog", &EditorNode::get_script_create_dialog);
+
ClassDB::bind_method("_sources_changed", &EditorNode::_sources_changed);
ClassDB::bind_method("_fs_changed", &EditorNode::_fs_changed);
ClassDB::bind_method("_dock_select_draw", &EditorNode::_dock_select_draw);
diff --git a/editor/editor_node.h b/editor/editor_node.h
index dedd947633d..a6c8141e196 100644
--- a/editor/editor_node.h
+++ b/editor/editor_node.h
@@ -598,6 +598,7 @@ public:
EditorPluginList *get_editor_plugins_force_input_forwarding() { return editor_plugins_force_input_forwarding; }
EditorInspector *get_inspector() { return inspector_dock->get_inspector(); }
Container *get_inspector_dock_addon_area() { return inspector_dock->get_addon_area(); }
+ ScriptCreateDialog *get_script_create_dialog() { return scene_tree_dock->get_script_create_dialog(); }
ProjectSettingsEditor *get_project_settings() { return project_settings; }
diff --git a/editor/editor_plugin.cpp b/editor/editor_plugin.cpp
index cc44938c25f..b95c1e6e302 100644
--- a/editor/editor_plugin.cpp
+++ b/editor/editor_plugin.cpp
@@ -717,6 +717,10 @@ EditorInterface *EditorPlugin::get_editor_interface() {
return EditorInterface::get_singleton();
}
+ScriptCreateDialog *EditorPlugin::get_script_create_dialog() {
+ return EditorNode::get_singleton()->get_script_create_dialog();
+}
+
void EditorPlugin::_bind_methods() {
ClassDB::bind_method(D_METHOD("add_control_to_container", "container", "control"), &EditorPlugin::add_control_to_container);
@@ -753,6 +757,7 @@ void EditorPlugin::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_force_draw_over_forwarding_enabled"), &EditorPlugin::set_force_draw_over_forwarding_enabled);
ClassDB::bind_method(D_METHOD("get_editor_interface"), &EditorPlugin::get_editor_interface);
+ ClassDB::bind_method(D_METHOD("get_script_create_dialog"), &EditorPlugin::get_script_create_dialog);
ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::BOOL, "forward_canvas_gui_input", PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent")));
ClassDB::add_virtual_method(get_class_static(), MethodInfo("forward_draw_over_viewport", PropertyInfo(Variant::OBJECT, "overlay", PROPERTY_HINT_RESOURCE_TYPE, "Control")));
diff --git a/editor/editor_plugin.h b/editor/editor_plugin.h
index fcc74cb1e97..72e21b2f7fe 100644
--- a/editor/editor_plugin.h
+++ b/editor/editor_plugin.h
@@ -34,6 +34,7 @@
#include "editor/editor_inspector.h"
#include "editor/import/editor_import_plugin.h"
#include "editor/import/resource_importer_scene.h"
+#include "editor/script_create_dialog.h"
#include "io/config_file.h"
#include "scene/gui/tool_button.h"
#include "scene/main/node.h"
@@ -195,6 +196,7 @@ public:
virtual bool build(); // builds with external tools. Returns true if safe to continue running scene.
EditorInterface *get_editor_interface();
+ ScriptCreateDialog *get_script_create_dialog();
int update_overlays() const;
diff --git a/editor/icons/icon_script_create_dialog.svg b/editor/icons/icon_script_create_dialog.svg
new file mode 100644
index 00000000000..27d6c47d49c
--- /dev/null
+++ b/editor/icons/icon_script_create_dialog.svg
@@ -0,0 +1,10 @@
+
diff --git a/editor/scene_tree_dock.h b/editor/scene_tree_dock.h
index ed13e063bb5..17deab25de5 100644
--- a/editor/scene_tree_dock.h
+++ b/editor/scene_tree_dock.h
@@ -215,6 +215,9 @@ public:
void replace_node(Node *p_node, Node *p_by_node);
void open_script_dialog(Node *p_for_node);
+
+ ScriptCreateDialog *get_script_create_dialog() { return script_create_dialog; }
+
SceneTreeDock(EditorNode *p_editor, Node *p_scene_root, EditorSelection *p_editor_selection, EditorData &p_editor_data);
};
diff --git a/editor/script_create_dialog.cpp b/editor/script_create_dialog.cpp
index 57a003060e1..24c4ba4cb7e 100644
--- a/editor/script_create_dialog.cpp
+++ b/editor/script_create_dialog.cpp
@@ -582,6 +582,9 @@ void ScriptCreateDialog::_bind_methods() {
ClassDB::bind_method("_path_changed", &ScriptCreateDialog::_path_changed);
ClassDB::bind_method("_path_entered", &ScriptCreateDialog::_path_entered);
ClassDB::bind_method("_template_changed", &ScriptCreateDialog::_template_changed);
+
+ ClassDB::bind_method(D_METHOD("config", "inherits", "path"), &ScriptCreateDialog::config);
+
ADD_SIGNAL(MethodInfo("script_created", PropertyInfo(Variant::OBJECT, "script", PROPERTY_HINT_RESOURCE_TYPE, "Script")));
}