Procházet zdrojové kódy

Merge pull request #8639 from n-pigeon/new_script_dialog

Reworked look and feel of Add Script Dialog also some bug fixes
Rémi Verschelde před 8 roky
rodič
revize
642a760952

+ 1 - 2
editor/scene_tree_dock.cpp

@@ -362,8 +362,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
 			else {
 				String path = selected->get_filename();
 				script_create_dialog->config(selected->get_class(), path);
-				script_create_dialog->popup_centered(Size2(300, 290));
-				//script_create_dialog->popup_centered_minsize();
+				script_create_dialog->popup_centered();
 			}
 
 		} break;

+ 372 - 147
editor/script_create_dialog.cpp

@@ -29,12 +29,23 @@
 /*************************************************************************/
 #include "script_create_dialog.h"
 
+#include "editor/editor_scale.h"
 #include "editor_file_system.h"
 #include "global_config.h"
 #include "io/resource_saver.h"
 #include "os/file_access.h"
 #include "script_language.h"
 
+void ScriptCreateDialog::_notification(int p_what) {
+
+	switch (p_what) {
+		case NOTIFICATION_ENTER_TREE: {
+			path_button->set_icon(get_icon("Folder", "EditorIcons"));
+			parent_browse_button->set_icon(get_icon("Folder", "EditorIcons"));
+		}
+	}
+}
+
 void ScriptCreateDialog::config(const String &p_base_name, const String &p_base_path) {
 
 	class_name->set_text("");
@@ -46,6 +57,8 @@ void ScriptCreateDialog::config(const String &p_base_name, const String &p_base_
 		initial_bp = "";
 		file_path->set_text("");
 	}
+	_lang_changed(current_language);
+	_parent_name_changed(parent_name->get_text());
 	_class_name_changed("");
 	_path_changed(file_path->get_text());
 }
@@ -85,54 +98,40 @@ bool ScriptCreateDialog::_validate(const String &p_string) {
 
 void ScriptCreateDialog::_class_name_changed(const String &p_name) {
 
-	if (!_validate(parent_name->get_text())) {
-		error_label->set_text(TTR("Invalid parent class name or path"));
-		error_label->add_color_override("font_color", Color(1, 0.4, 0.0, 0.8));
-	} else if (class_name->is_editable()) {
-		if (class_name->get_text() == "") {
-			error_label->set_text(TTR("Valid chars:") + " a-z A-Z 0-9 _");
-			error_label->add_color_override("font_color", Color(1, 1, 1, 0.6));
-		} else if (!_validate(class_name->get_text())) {
-			error_label->set_text(TTR("Invalid class name"));
-			error_label->add_color_override("font_color", Color(1, 0.2, 0.2, 0.8));
-		} else {
-			error_label->set_text(TTR("Valid name"));
-			error_label->add_color_override("font_color", Color(0, 1.0, 0.8, 0.8));
-		}
+	if (_validate(class_name->get_text())) {
+		is_class_name_valid = true;
 	} else {
+		is_class_name_valid = false;
+	}
+	_update_dialog();
+}
 
-		error_label->set_text(TTR("N/A"));
-		error_label->add_color_override("font_color", Color(0, 1.0, 0.8, 0.8));
+void ScriptCreateDialog::_parent_name_changed(const String &p_parent) {
+
+	if (_validate(parent_name->get_text())) {
+		is_parent_name_valid = true;
+	} else {
+		is_parent_name_valid = false;
 	}
+	_update_dialog();
 }
 
 void ScriptCreateDialog::ok_pressed() {
 
-	if (create_new) {
+	if (is_new_script_created) {
 		_create_new();
 	} else {
 		_load_exist();
 	}
 
-	create_new = true;
-	_update_controls();
+	is_new_script_created = true;
+	_update_dialog();
 }
 
 void ScriptCreateDialog::_create_new() {
 
-	if (class_name->is_editable() && !_validate(class_name->get_text())) {
-		alert->set_text(TTR("Class name is invalid!"));
-		alert->popup_centered_minsize();
-		return;
-	}
-	if (!_validate(parent_name->get_text())) {
-		alert->set_text(TTR("Parent class name is invalid!"));
-		alert->popup_centered_minsize();
-		return;
-	}
-
 	String cname;
-	if (class_name->is_editable())
+	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());
@@ -143,18 +142,13 @@ void ScriptCreateDialog::_create_new() {
 	if (cname != "")
 		scr->set_name(cname);
 
-	if (!internal->is_pressed()) {
+	if (!is_built_in) {
 		String lpath = GlobalConfig::get_singleton()->localize_path(file_path->get_text());
 		scr->set_path(lpath);
-		if (!path_valid) {
-			alert->set_text(TTR("Invalid path!"));
-			alert->popup_centered_minsize();
-			return;
-		}
 		Error err = ResourceSaver::save(lpath, scr, ResourceSaver::FLAG_CHANGE_PATH);
 		if (err != OK) {
-			alert->set_text(TTR("Could not create script in filesystem."));
-			alert->popup_centered_minsize();
+			alert->set_text(TTR("Error - Could not create script in filesystem."));
+			alert->popup_centered();
 			return;
 		}
 	}
@@ -168,9 +162,9 @@ void ScriptCreateDialog::_load_exist() {
 	String path = file_path->get_text();
 	RES p_script = ResourceLoader::load(path, "Script");
 	if (p_script.is_null()) {
-		alert->get_ok()->set_text(TTR("Ugh"));
+		alert->get_ok()->set_text(TTR("OK"));
 		alert->set_text(vformat(TTR("Error loading script from %s"), path));
-		alert->popup_centered_minsize();
+		alert->popup_centered();
 		return;
 	}
 
@@ -182,55 +176,59 @@ void ScriptCreateDialog::_lang_changed(int l) {
 
 	l = language_menu->get_selected();
 	if (ScriptServer::get_language(l)->has_named_classes()) {
-		class_name->set_editable(true);
+		has_named_classes = true;
 	} else {
-		class_name->set_editable(false);
+		has_named_classes = false;
 	}
 
 	if (ScriptServer::get_language(l)->can_inherit_from_file()) {
-		parent_browse_button->show();
+		can_inherit_from_file = true;
 	} else {
-		parent_browse_button->hide();
+		can_inherit_from_file = false;
 	}
 
 	String selected_ext = "." + ScriptServer::get_language(l)->get_extension();
 	String path = file_path->get_text();
 	String extension = "";
-	if (path.find(".") >= 0) {
-		extension = path.get_extension();
-	}
-
-	if (extension.length() == 0) {
-		// add extension if none
-		path += selected_ext;
-		_path_changed(path);
-	} else {
-		// change extension by selected language
-		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);
+	if (path != "") {
+		if (path.find(".") >= 0) {
+			extension = path.get_extension();
 		}
 
-		for (List<String>::Element *E = extensions.front(); E; E = E->next()) {
-			if (E->get().nocasecmp_to(extension) == 0) {
-				path = path.get_basename() + selected_ext;
-				_path_changed(path);
-				break;
+		if (extension.length() == 0) {
+			// add extension if none
+			path += selected_ext;
+			_path_changed(path);
+		} else {
+			// change extension by selected language
+			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);
+			}
+
+			for (List<String>::Element *E = extensions.front(); E; E = E->next()) {
+				if (E->get().nocasecmp_to(extension) == 0) {
+					path = path.get_basename() + selected_ext;
+					_path_changed(path);
+					break;
+				}
 			}
 		}
+		file_path->set_text(path);
 	}
-	file_path->set_text(path);
-	_class_name_changed(class_name->get_text());
+
+	_update_dialog();
 }
 
 void ScriptCreateDialog::_built_in_pressed() {
 
 	if (internal->is_pressed()) {
-		path_vb->hide();
+		is_built_in = true;
 	} else {
-		path_vb->show();
+		is_built_in = false;
 	}
+	_update_dialog();
 }
 
 void ScriptCreateDialog::_browse_path(bool browse_parent) {
@@ -269,40 +267,45 @@ void ScriptCreateDialog::_file_selected(const String &p_file) {
 
 void ScriptCreateDialog::_path_changed(const String &p_path) {
 
-	path_valid = false;
+	is_path_valid = false;
+	is_new_script_created = true;
 	String p = p_path;
 
 	if (p == "") {
-
-		path_error_label->set_text(TTR("Path is empty"));
-		path_error_label->add_color_override("font_color", Color(1, 0.4, 0.0, 0.8));
+		_msg_path_valid(false, TTR("Path is empty"));
+		_update_dialog();
 		return;
 	}
 
 	p = GlobalConfig::get_singleton()->localize_path(p);
 	if (!p.begins_with("res://")) {
-
-		path_error_label->set_text(TTR("Path is not local"));
-		path_error_label->add_color_override("font_color", Color(1, 0.4, 0.0, 0.8));
+		_msg_path_valid(false, TTR("Path is not local"));
+		_update_dialog();
 		return;
 	}
 
 	if (p.find("/") || p.find("\\")) {
 		DirAccess *d = DirAccess::create(DirAccess::ACCESS_RESOURCES);
-
 		if (d->change_dir(p.get_base_dir()) != OK) {
-
-			path_error_label->set_text(TTR("Invalid base path"));
-			path_error_label->add_color_override("font_color", Color(1, 0.4, 0.0, 0.8));
+			_msg_path_valid(false, TTR("Invalid base path"));
 			memdelete(d);
+			_update_dialog();
 			return;
 		}
 		memdelete(d);
 	}
 
-	FileAccess *f = FileAccess::create(FileAccess::ACCESS_RESOURCES);
-	create_new = !f->file_exists(p);
+	/* Does file already exist */
+
+	DirAccess *f = DirAccess::create(DirAccess::ACCESS_RESOURCES);
+	if (f->file_exists(p) && !(f->current_is_dir())) {
+		is_new_script_created = false;
+		is_path_valid = true;
+	}
 	memdelete(f);
+	_update_dialog();
+
+	/* Check file extension */
 
 	String extension = p.get_extension();
 	List<String> extensions;
@@ -313,45 +316,156 @@ void ScriptCreateDialog::_path_changed(const String &p_path) {
 	}
 
 	bool found = false;
+	bool match = false;
 	int index = 0;
 	for (List<String>::Element *E = extensions.front(); E; E = E->next()) {
 		if (E->get().nocasecmp_to(extension) == 0) {
-			language_menu->select(index); // change Language option by extension
+			//FIXME (?) - changing language this way doesn't update controls, needs rework
+			//language_menu->select(index); // change Language option by extension
 			found = true;
+			if (E->get() == ScriptServer::get_language(language_menu->get_selected())->get_extension()) {
+				match = true;
+			}
 			break;
 		}
 		index++;
 	}
 
 	if (!found) {
-		path_error_label->set_text(TTR("Invalid extension"));
-		path_error_label->add_color_override("font_color", Color(1, 0.4, 0.0, 0.8));
+		_msg_path_valid(false, TTR("Invalid extension"));
+		_update_dialog();
+		return;
+	}
+
+	if (!match) {
+		_msg_path_valid(false, TTR("Wrong extension chosen"));
+		_update_dialog();
 		return;
 	}
 
-	_update_controls();
+	/* All checks passed */
+
+	is_path_valid = true;
+	_update_dialog();
+}
+
+void ScriptCreateDialog::_msg_script_valid(bool valid, const String &p_msg) {
+
+	error_label->set_text(TTR(p_msg));
+	if (valid) {
+		error_label->add_color_override("font_color", Color(0, 1.0, 0.8, 0.8));
+	} else {
+		error_label->add_color_override("font_color", Color(1, 0.2, 0.2, 0.8));
+	}
+}
 
-	path_error_label->add_color_override("font_color", Color(0, 1.0, 0.8, 0.8));
+void ScriptCreateDialog::_msg_path_valid(bool valid, const String &p_msg) {
 
-	path_valid = true;
+	path_error_label->set_text(TTR(p_msg));
+	if (valid) {
+		path_error_label->add_color_override("font_color", Color(0, 1.0, 0.8, 0.8));
+	} else {
+		path_error_label->add_color_override("font_color", Color(1, 0.4, 0.0, 0.8));
+	}
 }
 
-void ScriptCreateDialog::_update_controls() {
+void ScriptCreateDialog::_update_dialog() {
+
+	bool script_ok = true;
+
+	/* "Add Script Dialog" gui logic and script checks */
+
+	// Is Script Valid (order from top to bottom)
+	get_ok()->set_disabled(true);
+	if (!is_built_in) {
+		if (!is_path_valid) {
+			_msg_script_valid(false, TTR("Invalid Path"));
+			script_ok = false;
+		}
+	}
+	if (has_named_classes && (!is_class_name_valid)) {
+		_msg_script_valid(false, TTR("Invalid class name"));
+		script_ok = false;
+	}
+	if (!is_parent_name_valid) {
+		_msg_script_valid(false, TTR("Invalid inherited parent name or path"));
+		script_ok = false;
+	}
+	if (script_ok) {
+		_msg_script_valid(true, TTR("Script valid"));
+		get_ok()->set_disabled(false);
+	}
+
+	/* Does script have named classes */
 
-	if (create_new) {
-		path_error_label->set_text(TTR("Create new script"));
+	if (has_named_classes) {
+		if (is_new_script_created) {
+			class_name->set_editable(true);
+			class_name->set_placeholder(TTR("Allowed: a-z, A-Z, 0-9 and _"));
+			class_name->set_placeholder_alpha(0.3);
+		} else {
+			class_name->set_editable(false);
+		}
+	} else {
+		class_name->set_editable(false);
+		class_name->set_placeholder(TTR("N/A"));
+		class_name->set_placeholder_alpha(1);
+	}
+
+	/* Can script inherit from a file */
+
+	if (can_inherit_from_file) {
+		parent_browse_button->set_disabled(false);
+	} else {
+		parent_browse_button->set_disabled(true);
+	}
+
+	/* Is script Built-in */
+
+	if (is_built_in) {
+		file_path->set_editable(false);
+		path_button->set_disabled(true);
+		re_check_path = true;
+	} else {
+		file_path->set_editable(true);
+		path_button->set_disabled(false);
+		if (re_check_path) {
+			re_check_path = false;
+			_path_changed(file_path->get_text());
+		}
+	}
+
+	/* Is Script created or loaded from existing file */
+
+	if (is_new_script_created) {
+		// New Script Created
 		get_ok()->set_text(TTR("Create"));
+		parent_name->set_editable(true);
+		parent_browse_button->set_disabled(false);
+		internal->set_disabled(false);
+		if (is_built_in) {
+			_msg_path_valid(true, TTR("Built-in script (into scene file)"));
+		} else {
+			if (script_ok) {
+				_msg_path_valid(true, TTR("Create new script file"));
+			}
+		}
 	} else {
-		path_error_label->set_text(TTR("Load existing script"));
+		// Script Loaded
 		get_ok()->set_text(TTR("Load"));
+		parent_name->set_editable(false);
+		parent_browse_button->set_disabled(true);
+		internal->set_disabled(true);
+		if (script_ok) {
+			_msg_path_valid(true, TTR("Load existing script file"));
+		}
 	}
-	parent_name->set_editable(create_new);
-	internal->set_disabled(!create_new);
 }
 
 void ScriptCreateDialog::_bind_methods() {
 
 	ClassDB::bind_method("_class_name_changed", &ScriptCreateDialog::_class_name_changed);
+	ClassDB::bind_method("_parent_name_changed", &ScriptCreateDialog::_parent_name_changed);
 	ClassDB::bind_method("_lang_changed", &ScriptCreateDialog::_lang_changed);
 	ClassDB::bind_method("_built_in_pressed", &ScriptCreateDialog::_built_in_pressed);
 	ClassDB::bind_method("_browse_path", &ScriptCreateDialog::_browse_path);
@@ -362,37 +476,100 @@ void ScriptCreateDialog::_bind_methods() {
 
 ScriptCreateDialog::ScriptCreateDialog() {
 
-	/* SNAP DIALOG */
+	editor_settings = EditorSettings::get_singleton();
 
+	GridContainer *gc = memnew(GridContainer);
 	VBoxContainer *vb = memnew(VBoxContainer);
-	add_child(vb);
-	//set_child_rect(vb);
+	HBoxContainer *hb = memnew(HBoxContainer);
+	Label *l = memnew(Label);
+	Control *empty = memnew(Control);
+	Control *empty_h = memnew(Control);
+	Control *empty_v = memnew(Control);
+	PanelContainer *pc = memnew(PanelContainer);
 
-	class_name = memnew(LineEdit);
-	VBoxContainer *vb2 = memnew(VBoxContainer);
-	vb2->add_child(class_name);
-	class_name->connect("text_changed", this, "_class_name_changed");
-	error_label = memnew(Label);
-	error_label->set_text("valid chars: a-z A-Z 0-9 _");
-	error_label->set_align(Label::ALIGN_CENTER);
-	vb2->add_child(error_label);
-	vb->add_margin_child(TTR("Class Name:"), vb2);
+	/* DIALOG */
 
-	HBoxContainer *hb1 = memnew(HBoxContainer);
-	parent_name = memnew(LineEdit);
-	parent_name->connect("text_changed", this, "_class_name_changed");
-	parent_name->set_h_size_flags(SIZE_EXPAND_FILL);
-	hb1->add_child(parent_name);
-	parent_browse_button = memnew(Button);
-	parent_browse_button->set_text(" .. ");
-	parent_browse_button->connect("pressed", this, "_browse_path", varray(true));
-	hb1->add_child(parent_browse_button);
-	parent_browse_button->hide();
-	vb->add_margin_child(TTR("Inherits:"), hb1);
-	is_browsing_parent = false;
+	/* Main Controls */
+
+	gc = memnew(GridContainer);
+	gc->set_columns(2);
+
+	/* Error Stylebox Background */
+
+	StyleBoxFlat *sb = memnew(StyleBoxFlat);
+	sb->set_bg_color(Color(0, 0, 0, 0.05));
+	sb->set_light_color(Color(1, 1, 1, 0.05));
+	sb->set_dark_color(Color(1, 1, 1, 0.05));
+	sb->set_border_blend(false);
+	sb->set_border_size(1);
+	sb->set_default_margin(MARGIN_TOP, 10.0 * EDSCALE);
+	sb->set_default_margin(MARGIN_BOTTOM, 10.0 * EDSCALE);
+	sb->set_default_margin(MARGIN_LEFT, 10.0 * EDSCALE);
+	sb->set_default_margin(MARGIN_RIGHT, 10.0 * EDSCALE);
+
+	/* Error Messages Field */
+
+	vb = memnew(VBoxContainer);
+
+	hb = memnew(HBoxContainer);
+	l = memnew(Label);
+	l->set_text(" - ");
+	hb->add_child(l);
+	error_label = memnew(Label);
+	error_label->set_text(TTR("Error!"));
+	error_label->set_align(Label::ALIGN_LEFT);
+	hb->add_child(error_label);
+	vb->add_child(hb);
+
+	hb = memnew(HBoxContainer);
+	l = memnew(Label);
+	l->set_text(" - ");
+	hb->add_child(l);
+	path_error_label = memnew(Label);
+	path_error_label->set_text(TTR("Error!"));
+	path_error_label->set_align(Label::ALIGN_LEFT);
+	hb->add_child(path_error_label);
+	vb->add_child(hb);
+
+	pc = memnew(PanelContainer);
+	pc->set_h_size_flags(Control::SIZE_FILL);
+	pc->add_style_override("panel", sb);
+	pc->add_child(vb);
+
+	/* Margins */
+
+	empty_h = memnew(Control);
+	empty_h->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+	empty_h->set_v_size_flags(Control::SIZE_EXPAND_FILL);
+	empty_h->set_custom_minimum_size(Size2(0, 10 * EDSCALE));
+	empty_v = memnew(Control);
+	empty_v->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+	empty_v->set_v_size_flags(Control::SIZE_EXPAND_FILL);
+	empty_v->set_custom_minimum_size(Size2(10, 0 * EDSCALE));
+
+	vb = memnew(VBoxContainer);
+	vb->add_child(empty_h->duplicate());
+	vb->add_child(gc);
+	vb->add_child(empty_h->duplicate());
+	vb->add_child(pc);
+	vb->add_child(empty_h->duplicate());
+	hb = memnew(HBoxContainer);
+	hb->add_child(empty_v->duplicate());
+	hb->add_child(vb);
+	hb->add_child(empty_v->duplicate());
+
+	add_child(hb);
+
+	/* Language */
 
 	language_menu = memnew(OptionButton);
-	vb->add_margin_child(TTR("Language"), language_menu);
+	language_menu->set_custom_minimum_size(Size2(250, 0) * EDSCALE);
+	language_menu->set_h_size_flags(SIZE_EXPAND_FILL);
+	l = memnew(Label);
+	l->set_text(TTR("Language"));
+	l->set_align(Label::ALIGN_RIGHT);
+	gc->add_child(l);
+	gc->add_child(language_menu);
 
 	int default_lang = 0;
 	for (int i = 0; i < ScriptServer::get_language_count(); i++) {
@@ -404,60 +581,108 @@ ScriptCreateDialog::ScriptCreateDialog() {
 		}
 	}
 
-	editor_settings = EditorSettings::get_singleton();
 	String last_selected_language = editor_settings->get_project_metadata("script_setup", "last_selected_language", "");
 	if (last_selected_language != "") {
 		for (int i = 0; i < language_menu->get_item_count(); i++) {
 			if (language_menu->get_item_text(i) == last_selected_language) {
 				language_menu->select(i);
+				current_language = i;
 				break;
 			}
 		}
 	} else {
 		language_menu->select(default_lang);
+		current_language = default_lang;
 	}
 
 	language_menu->connect("item_selected", this, "_lang_changed");
 
-	//parent_name->set_text();
+	/* Inherits */
 
-	vb2 = memnew(VBoxContainer);
-	path_vb = memnew(VBoxContainer);
-	vb2->add_child(path_vb);
+	hb = memnew(HBoxContainer);
+	hb->set_h_size_flags(SIZE_EXPAND_FILL);
+	parent_name = memnew(LineEdit);
+	parent_name->connect("text_changed", this, "_parent_name_changed");
+	parent_name->set_h_size_flags(SIZE_EXPAND_FILL);
+	hb->add_child(parent_name);
+	parent_browse_button = memnew(Button);
+	parent_browse_button->set_flat(true);
+	parent_browse_button->connect("pressed", this, "_browse_path", varray(true));
+	hb->add_child(parent_browse_button);
+	l = memnew(Label);
+	l->set_text(TTR("Inherits"));
+	l->set_align(Label::ALIGN_RIGHT);
+	gc->add_child(l);
+	gc->add_child(hb);
+	is_browsing_parent = false;
 
-	HBoxContainer *hbc = memnew(HBoxContainer);
-	file_path = memnew(LineEdit);
-	file_path->connect("text_changed", this, "_path_changed");
-	hbc->add_child(file_path);
-	file_path->set_h_size_flags(SIZE_EXPAND_FILL);
-	Button *b = memnew(Button);
-	b->set_text(" .. ");
-	b->connect("pressed", this, "_browse_path", varray(false));
-	hbc->add_child(b);
-	path_vb->add_child(hbc);
-	path_error_label = memnew(Label);
-	path_vb->add_child(path_error_label);
-	path_error_label->set_text(TTR("Error!"));
-	path_error_label->set_align(Label::ALIGN_CENTER);
+	/* Class Name */
 
-	internal = memnew(CheckButton);
-	internal->set_text(TTR("Built-In Script"));
-	vb2->add_child(internal);
-	internal->connect("pressed", this, "_built_in_pressed");
+	class_name = memnew(LineEdit);
+	class_name->connect("text_changed", this, "_class_name_changed");
+	class_name->set_h_size_flags(SIZE_EXPAND_FILL);
+	l = memnew(Label);
+	l->set_text(TTR("Class Name"));
+	l->set_align(Label::ALIGN_RIGHT);
+	gc->add_child(l);
+	gc->add_child(class_name);
 
-	vb->add_margin_child(TTR("Path:"), vb2);
+	/* Built-in Script */
 
-	set_size(Size2(200, 150));
-	set_hide_on_ok(false);
-	set_title(TTR("Attach Node Script"));
+	internal = memnew(CheckButton);
+	internal->connect("pressed", this, "_built_in_pressed");
+	hb = memnew(HBoxContainer);
+	empty = memnew(Control);
+	hb->add_child(internal);
+	hb->add_child(empty);
+	l = memnew(Label);
+	l->set_text(TTR("Built-in Script"));
+	l->set_align(Label::ALIGN_RIGHT);
+	gc->add_child(l);
+	gc->add_child(hb);
+
+	/* Path */
+
+	hb = memnew(HBoxContainer);
+	file_path = memnew(LineEdit);
+	file_path->connect("text_changed", this, "_path_changed");
+	file_path->set_h_size_flags(SIZE_EXPAND_FILL);
+	hb->add_child(file_path);
+	path_button = memnew(Button);
+	path_button->set_flat(true);
+	path_button->connect("pressed", this, "_browse_path", varray(false));
+	hb->add_child(path_button);
+	l = memnew(Label);
+	l->set_text(TTR("Path"));
+	l->set_align(Label::ALIGN_RIGHT);
+	gc->add_child(l);
+	gc->add_child(hb);
+
+	/* Dialog Setup */
 
 	file_browse = memnew(EditorFileDialog);
 	file_browse->connect("file_selected", this, "_file_selected");
 	add_child(file_browse);
 	get_ok()->set_text(TTR("Create"));
 	alert = memnew(AcceptDialog);
+	alert->set_as_minsize();
+	alert->get_label()->set_autowrap(true);
+	alert->get_label()->set_align(Label::ALIGN_CENTER);
+	alert->get_label()->set_valign(Label::VALIGN_CENTER);
+	alert->get_label()->set_custom_minimum_size(Size2(325, 60) * EDSCALE);
 	add_child(alert);
-	_lang_changed(0);
 
-	create_new = true;
+	set_as_minsize();
+	set_hide_on_ok(false);
+	set_title(TTR("Attach Node Script"));
+
+	is_parent_name_valid = false;
+	is_class_name_valid = false;
+	is_path_valid = false;
+
+	has_named_classes = false;
+	can_inherit_from_file = false;
+	is_built_in = false;
+
+	is_new_script_created = true;
 }

+ 17 - 1
editor/script_create_dialog.h

@@ -34,8 +34,10 @@
 #include "editor/editor_settings.h"
 #include "scene/gui/check_button.h"
 #include "scene/gui/dialogs.h"
+#include "scene/gui/grid_container.h"
 #include "scene/gui/line_edit.h"
 #include "scene/gui/option_button.h"
+#include "scene/gui/panel_container.h"
 
 class ScriptCreateDialog : public ConfirmationDialog {
 	GDCLASS(ScriptCreateDialog, ConfirmationDialog);
@@ -47,6 +49,7 @@ class ScriptCreateDialog : public ConfirmationDialog {
 	Button *parent_browse_button;
 	OptionButton *language_menu;
 	LineEdit *file_path;
+	Button *path_button;
 	EditorFileDialog *file_browse;
 	CheckButton *internal;
 	VBoxContainer *path_vb;
@@ -56,20 +59,33 @@ class ScriptCreateDialog : public ConfirmationDialog {
 	bool is_browsing_parent;
 	String initial_bp;
 	EditorSettings *editor_settings;
+	bool is_new_script_created;
+	bool is_path_valid;
+	bool has_named_classes;
+	bool can_inherit_from_file;
+	bool is_parent_name_valid;
+	bool is_class_name_valid;
+	bool is_built_in;
+	int current_language;
+	bool re_check_path;
 
 	void _path_changed(const String &p_path = String());
 	void _lang_changed(int l = 0);
 	void _built_in_pressed();
 	bool _validate(const String &p_strin);
 	void _class_name_changed(const String &p_name);
+	void _parent_name_changed(const String &p_parent);
 	void _browse_path(bool browse_parent);
 	void _file_selected(const String &p_file);
 	virtual void ok_pressed();
 	void _create_new();
 	void _load_exist();
-	void _update_controls();
+	void _msg_script_valid(bool valid, const String &p_msg = String());
+	void _msg_path_valid(bool valid, const String &p_msg = String());
+	void _update_dialog();
 
 protected:
+	void _notification(int p_what);
 	static void _bind_methods();
 
 public: