summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Haas <hinsbart@gmail.com>2017-06-13 20:03:08 +0000
committerAndreas Haas <hinsbart@gmail.com>2017-06-13 20:03:08 +0000
commit8361b1ce07266350ef6b6a2d34411030b7e587b2 (patch)
treeff9cab7037410224c1b76aab30f394305b523fe8
parenta8a1f2e2a864e6b58d5bcf1c7e53a43cdb6d95d9 (diff)
Add ability to use custom script templates.
Templates will be loaded from .godot/script_templates For now they're disabled for GDNative. Ideas for further improvements: - Add a "Save as Template" option to the script editor, as it can normally only save to res:// - Support more placeholders / custom placeholders
-rw-r--r--core/script_language.h2
-rw-r--r--editor/editor_settings.cpp25
-rw-r--r--editor/editor_settings.h2
-rw-r--r--editor/script_create_dialog.cpp50
-rw-r--r--editor/script_create_dialog.h3
-rw-r--r--modules/gdscript/gd_editor.cpp13
-rw-r--r--modules/gdscript/gd_script.cpp5
-rw-r--r--modules/gdscript/gd_script.h2
-rw-r--r--modules/visual_script/visual_script.cpp11
-rw-r--r--modules/visual_script/visual_script.h2
10 files changed, 111 insertions, 4 deletions
diff --git a/core/script_language.h b/core/script_language.h
index 115ab59dca..6e39593a89 100644
--- a/core/script_language.h
+++ b/core/script_language.h
@@ -196,6 +196,8 @@ public:
virtual void get_comment_delimiters(List<String> *p_delimiters) const = 0;
virtual void get_string_delimiters(List<String> *p_delimiters) const = 0;
virtual Ref<Script> get_template(const String &p_class_name, const String &p_base_class_name) const = 0;
+ virtual void make_template(const String &p_class_name, const String &p_base_class_name, Ref<Script> &p_script) {}
+ virtual bool is_using_templates() { return false; }
virtual bool validate(const String &p_script, int &r_line_error, int &r_col_error, String &r_test_error, const String &p_path = "", List<String> *r_functions = NULL) const = 0;
virtual Script *create_script() const = 0;
virtual bool has_named_classes() const = 0;
diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp
index 07c7fe97e4..3627a43279 100644
--- a/editor/editor_settings.cpp
+++ b/editor/editor_settings.cpp
@@ -292,6 +292,12 @@ void EditorSettings::create() {
dir->change_dir("..");
}
+ if (dir->change_dir("script_templates") != OK) {
+ dir->make_dir("script_templates");
+ } else {
+ dir->change_dir("..");
+ }
+
if (dir->change_dir("tmp") != OK) {
dir->make_dir("tmp");
} else {
@@ -946,6 +952,25 @@ bool EditorSettings::save_text_editor_theme_as(String p_file) {
return false;
}
+Vector<String> EditorSettings::get_script_templates(const String &p_extension) {
+
+ Vector<String> templates;
+ DirAccess *d = DirAccess::open(settings_path + "/script_templates");
+ if (d) {
+ d->list_dir_begin();
+ String file = d->get_next();
+ while (file != String()) {
+ if (file.get_extension() == p_extension) {
+ templates.push_back(file.get_basename());
+ }
+ file = d->get_next();
+ }
+ d->list_dir_end();
+ memdelete(d);
+ }
+ return templates;
+}
+
bool EditorSettings::_save_text_editor_theme(String p_file) {
String theme_section = "color_theme";
Ref<ConfigFile> cf = memnew(ConfigFile); // hex is better?
diff --git a/editor/editor_settings.h b/editor/editor_settings.h
index 7b45e28350..d5adb84b63 100644
--- a/editor/editor_settings.h
+++ b/editor/editor_settings.h
@@ -159,6 +159,8 @@ public:
bool save_text_editor_theme();
bool save_text_editor_theme_as(String p_file);
+ Vector<String> get_script_templates(const String &p_extension);
+
void add_shortcut(const String &p_name, Ref<ShortCut> &p_shortcut);
bool is_shortcut(const String &p_name, const Ref<InputEvent> &p_event) const;
Ref<ShortCut> get_shortcut(const String &p_name) const;
diff --git a/editor/script_create_dialog.cpp b/editor/script_create_dialog.cpp
index 2220e3330f..dbd0758256 100644
--- a/editor/script_create_dialog.cpp
+++ b/editor/script_create_dialog.cpp
@@ -116,6 +116,18 @@ void ScriptCreateDialog::_parent_name_changed(const String &p_parent) {
_update_dialog();
}
+void ScriptCreateDialog::_template_changed(int p_template) {
+
+ if (p_template == 0) {
+ //default
+ script_template = "";
+ return;
+ }
+ String ext = ScriptServer::get_language(language_menu->get_selected())->get_extension();
+ String name = template_menu->get_item_text(p_template) + "." + ext;
+ script_template = EditorSettings::get_singleton()->get_settings_path() + "/script_templates/" + name;
+}
+
void ScriptCreateDialog::ok_pressed() {
if (is_new_script_created) {
@@ -134,7 +146,13 @@ void ScriptCreateDialog::_create_new() {
if (has_named_classes)
cname = class_name->get_text();
- Ref<Script> scr = ScriptServer::get_language(language_menu->get_selected())->get_template(cname, parent_name->get_text());
+ Ref<Script> scr;
+ if (script_template != "") {
+ scr = ResourceLoader::load(script_template)->duplicate();
+ ScriptServer::get_language(language_menu->get_selected())->make_template(cname, parent_name->get_text(), scr);
+ } else {
+ scr = ScriptServer::get_language(language_menu->get_selected())->get_template(cname, parent_name->get_text());
+ }
String selected_language = language_menu->get_item_text(language_menu->get_selected());
editor_settings->set_project_metadata("script_setup", "last_selected_language", selected_language);
@@ -175,7 +193,8 @@ void ScriptCreateDialog::_load_exist() {
void ScriptCreateDialog::_lang_changed(int l) {
l = language_menu->get_selected();
- if (ScriptServer::get_language(l)->has_named_classes()) {
+ ScriptLanguage *language = ScriptServer::get_language(l);
+ if (language->has_named_classes()) {
has_named_classes = true;
} else {
has_named_classes = false;
@@ -187,7 +206,7 @@ void ScriptCreateDialog::_lang_changed(int l) {
can_inherit_from_file = false;
}
- String selected_ext = "." + ScriptServer::get_language(l)->get_extension();
+ String selected_ext = "." + language->get_extension();
String path = file_path->get_text();
String extension = "";
if (path != "") {
@@ -204,7 +223,7 @@ void ScriptCreateDialog::_lang_changed(int l) {
List<String> extensions;
// get all possible extensions for script
for (int l = 0; l < language_menu->get_item_count(); l++) {
- ScriptServer::get_language(l)->get_recognized_extensions(&extensions);
+ language->get_recognized_extensions(&extensions);
}
for (List<String>::Element *E = extensions.front(); E; E = E->next()) {
@@ -218,6 +237,18 @@ void ScriptCreateDialog::_lang_changed(int l) {
file_path->set_text(path);
}
+ bool use_templates = language->is_using_templates();
+ template_menu->set_disabled(!use_templates);
+ if (use_templates) {
+ Vector<String> template_list = EditorSettings::get_singleton()->get_script_templates(language->get_extension());
+
+ template_menu->clear();
+ template_menu->add_item(TTR("Default"));
+ for (int i = 0; i < template_list.size(); i++) {
+ template_menu->add_item(template_list[i]);
+ }
+ }
+
_update_dialog();
}
@@ -471,6 +502,7 @@ void ScriptCreateDialog::_bind_methods() {
ClassDB::bind_method("_browse_path", &ScriptCreateDialog::_browse_path);
ClassDB::bind_method("_file_selected", &ScriptCreateDialog::_file_selected);
ClassDB::bind_method("_path_changed", &ScriptCreateDialog::_path_changed);
+ ClassDB::bind_method("_template_changed", &ScriptCreateDialog::_template_changed);
ADD_SIGNAL(MethodInfo("script_created", PropertyInfo(Variant::OBJECT, "script", PROPERTY_HINT_RESOURCE_TYPE, "Script")));
}
@@ -629,6 +661,16 @@ ScriptCreateDialog::ScriptCreateDialog() {
gc->add_child(l);
gc->add_child(class_name);
+ /* Templates */
+
+ template_menu = memnew(OptionButton);
+ l = memnew(Label);
+ l->set_text(TTR("Template"));
+ l->set_align(Label::ALIGN_RIGHT);
+ gc->add_child(l);
+ gc->add_child(template_menu);
+ template_menu->connect("item_selected", this, "_template_changed");
+
/* Built-in Script */
internal = memnew(CheckButton);
diff --git a/editor/script_create_dialog.h b/editor/script_create_dialog.h
index 862d4f88f2..1adbfe3f7d 100644
--- a/editor/script_create_dialog.h
+++ b/editor/script_create_dialog.h
@@ -48,6 +48,7 @@ class ScriptCreateDialog : public ConfirmationDialog {
LineEdit *parent_name;
Button *parent_browse_button;
OptionButton *language_menu;
+ OptionButton *template_menu;
LineEdit *file_path;
Button *path_button;
EditorFileDialog *file_browse;
@@ -68,6 +69,7 @@ class ScriptCreateDialog : public ConfirmationDialog {
bool is_built_in;
int current_language;
bool re_check_path;
+ String script_template;
void _path_changed(const String &p_path = String());
void _lang_changed(int l = 0);
@@ -75,6 +77,7 @@ class ScriptCreateDialog : public ConfirmationDialog {
bool _validate(const String &p_strin);
void _class_name_changed(const String &p_name);
void _parent_name_changed(const String &p_parent);
+ void _template_changed(int p_template = 0);
void _browse_path(bool browse_parent);
void _file_selected(const String &p_file);
virtual void ok_pressed();
diff --git a/modules/gdscript/gd_editor.cpp b/modules/gdscript/gd_editor.cpp
index eea5b15236..5e3ce31dd6 100644
--- a/modules/gdscript/gd_editor.cpp
+++ b/modules/gdscript/gd_editor.cpp
@@ -69,6 +69,19 @@ Ref<Script> GDScriptLanguage::get_template(const String &p_class_name, const Str
return script;
}
+bool GDScriptLanguage::is_using_templates() {
+
+ return true;
+}
+
+void GDScriptLanguage::make_template(const String &p_class_name, const String &p_base_class_name, Ref<Script> &p_script) {
+
+ String src = p_script->get_source_code();
+ src = src.replace("%BASE%", p_base_class_name);
+ src = src.replace("%TS%", _get_indentation());
+ p_script->set_source_code(src);
+}
+
bool GDScriptLanguage::validate(const String &p_script, int &r_line_error, int &r_col_error, String &r_test_error, const String &p_path, List<String> *r_functions) const {
GDParser parser;
diff --git a/modules/gdscript/gd_script.cpp b/modules/gdscript/gd_script.cpp
index dcc0e24098..1dcc442234 100644
--- a/modules/gdscript/gd_script.cpp
+++ b/modules/gdscript/gd_script.cpp
@@ -615,6 +615,11 @@ Error GDScript::reload(bool p_keep_state) {
if (basedir != "")
basedir = basedir.get_base_dir();
+ if (basedir.find("res://") == -1 && basedir.find("user://") == -1) {
+ //loading a template, don't parse
+ return OK;
+ }
+
valid = false;
GDParser parser;
Error err = parser.parse(source, basedir, false, path);
diff --git a/modules/gdscript/gd_script.h b/modules/gdscript/gd_script.h
index 00ae136790..ebef4fed74 100644
--- a/modules/gdscript/gd_script.h
+++ b/modules/gdscript/gd_script.h
@@ -381,6 +381,8 @@ public:
virtual void get_comment_delimiters(List<String> *p_delimiters) const;
virtual void get_string_delimiters(List<String> *p_delimiters) const;
virtual Ref<Script> get_template(const String &p_class_name, const String &p_base_class_name) const;
+ virtual bool is_using_templates();
+ virtual void make_template(const String &p_class_name, const String &p_base_class_name, Ref<Script> &p_script);
virtual bool validate(const String &p_script, int &r_line_error, int &r_col_error, String &r_test_error, const String &p_path = "", List<String> *r_functions = NULL) const;
virtual Script *create_script() const;
virtual bool has_named_classes() const;
diff --git a/modules/visual_script/visual_script.cpp b/modules/visual_script/visual_script.cpp
index aec60391d3..bb8111ce99 100644
--- a/modules/visual_script/visual_script.cpp
+++ b/modules/visual_script/visual_script.cpp
@@ -2369,6 +2369,17 @@ Ref<Script> VisualScriptLanguage::get_template(const String &p_class_name, const
script->set_instance_base_type(p_base_class_name);
return script;
}
+
+bool VisualScriptLanguage::is_using_templates() {
+
+ return true;
+}
+
+void VisualScriptLanguage::make_template(const String &p_class_name, const String &p_base_class_name, Ref<Script> &p_script) {
+ Ref<VisualScript> script = p_script;
+ script->set_instance_base_type(p_base_class_name);
+}
+
bool VisualScriptLanguage::validate(const String &p_script, int &r_line_error, int &r_col_error, String &r_test_error, const String &p_path, List<String> *r_functions) const {
return false;
diff --git a/modules/visual_script/visual_script.h b/modules/visual_script/visual_script.h
index 72843099c7..1ccc358342 100644
--- a/modules/visual_script/visual_script.h
+++ b/modules/visual_script/visual_script.h
@@ -564,6 +564,8 @@ public:
virtual void get_comment_delimiters(List<String> *p_delimiters) const;
virtual void get_string_delimiters(List<String> *p_delimiters) const;
virtual Ref<Script> get_template(const String &p_class_name, const String &p_base_class_name) const;
+ virtual bool is_using_templates();
+ virtual void make_template(const String &p_class_name, const String &p_base_class_name, Ref<Script> &p_script);
virtual bool validate(const String &p_script, int &r_line_error, int &r_col_error, String &r_test_error, const String &p_path = "", List<String> *r_functions = NULL) const;
virtual Script *create_script() const;
virtual bool has_named_classes() const;