script_create_dialog.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688
  1. /*************************************************************************/
  2. /* script_create_dialog.cpp */
  3. /*************************************************************************/
  4. /* This file is part of: */
  5. /* GODOT ENGINE */
  6. /* http://www.godotengine.org */
  7. /*************************************************************************/
  8. /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
  9. /* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
  10. /* */
  11. /* Permission is hereby granted, free of charge, to any person obtaining */
  12. /* a copy of this software and associated documentation files (the */
  13. /* "Software"), to deal in the Software without restriction, including */
  14. /* without limitation the rights to use, copy, modify, merge, publish, */
  15. /* distribute, sublicense, and/or sell copies of the Software, and to */
  16. /* permit persons to whom the Software is furnished to do so, subject to */
  17. /* the following conditions: */
  18. /* */
  19. /* The above copyright notice and this permission notice shall be */
  20. /* included in all copies or substantial portions of the Software. */
  21. /* */
  22. /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
  23. /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
  24. /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
  25. /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
  26. /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
  27. /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
  28. /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
  29. /*************************************************************************/
  30. #include "script_create_dialog.h"
  31. #include "editor/editor_scale.h"
  32. #include "editor_file_system.h"
  33. #include "global_config.h"
  34. #include "io/resource_saver.h"
  35. #include "os/file_access.h"
  36. #include "script_language.h"
  37. void ScriptCreateDialog::_notification(int p_what) {
  38. switch (p_what) {
  39. case NOTIFICATION_ENTER_TREE: {
  40. path_button->set_icon(get_icon("Folder", "EditorIcons"));
  41. parent_browse_button->set_icon(get_icon("Folder", "EditorIcons"));
  42. }
  43. }
  44. }
  45. void ScriptCreateDialog::config(const String &p_base_name, const String &p_base_path) {
  46. class_name->set_text("");
  47. parent_name->set_text(p_base_name);
  48. if (p_base_path != "") {
  49. initial_bp = p_base_path.get_basename();
  50. file_path->set_text(initial_bp + "." + ScriptServer::get_language(language_menu->get_selected())->get_extension());
  51. } else {
  52. initial_bp = "";
  53. file_path->set_text("");
  54. }
  55. _lang_changed(current_language);
  56. _parent_name_changed(parent_name->get_text());
  57. _class_name_changed("");
  58. _path_changed(file_path->get_text());
  59. }
  60. bool ScriptCreateDialog::_validate(const String &p_string) {
  61. if (p_string.length() == 0)
  62. return false;
  63. String path_chars = "\"res://";
  64. bool is_val_path = ScriptServer::get_language(language_menu->get_selected())->can_inherit_from_file();
  65. for (int i = 0; i < p_string.length(); i++) {
  66. if (i == 0) {
  67. if (p_string[0] >= '0' && p_string[0] <= '9')
  68. return false; // no start with number plz
  69. }
  70. if (i == p_string.length() - 1 && is_val_path)
  71. return p_string[i] == '\"';
  72. if (is_val_path && i < path_chars.length()) {
  73. if (p_string[i] != path_chars[i])
  74. is_val_path = false;
  75. else
  76. continue;
  77. }
  78. bool valid_char = (p_string[i] >= '0' && p_string[i] <= '9') || (p_string[i] >= 'a' && p_string[i] <= 'z') || (p_string[i] >= 'A' && p_string[i] <= 'Z') || p_string[i] == '_' || (is_val_path && (p_string[i] == '/' || p_string[i] == '.'));
  79. if (!valid_char)
  80. return false;
  81. }
  82. return true;
  83. }
  84. void ScriptCreateDialog::_class_name_changed(const String &p_name) {
  85. if (_validate(class_name->get_text())) {
  86. is_class_name_valid = true;
  87. } else {
  88. is_class_name_valid = false;
  89. }
  90. _update_dialog();
  91. }
  92. void ScriptCreateDialog::_parent_name_changed(const String &p_parent) {
  93. if (_validate(parent_name->get_text())) {
  94. is_parent_name_valid = true;
  95. } else {
  96. is_parent_name_valid = false;
  97. }
  98. _update_dialog();
  99. }
  100. void ScriptCreateDialog::ok_pressed() {
  101. if (is_new_script_created) {
  102. _create_new();
  103. } else {
  104. _load_exist();
  105. }
  106. is_new_script_created = true;
  107. _update_dialog();
  108. }
  109. void ScriptCreateDialog::_create_new() {
  110. String cname;
  111. if (has_named_classes)
  112. cname = class_name->get_text();
  113. Ref<Script> scr = ScriptServer::get_language(language_menu->get_selected())->get_template(cname, parent_name->get_text());
  114. String selected_language = language_menu->get_item_text(language_menu->get_selected());
  115. editor_settings->set_project_metadata("script_setup", "last_selected_language", selected_language);
  116. if (cname != "")
  117. scr->set_name(cname);
  118. if (!is_built_in) {
  119. String lpath = GlobalConfig::get_singleton()->localize_path(file_path->get_text());
  120. scr->set_path(lpath);
  121. Error err = ResourceSaver::save(lpath, scr, ResourceSaver::FLAG_CHANGE_PATH);
  122. if (err != OK) {
  123. alert->set_text(TTR("Error - Could not create script in filesystem."));
  124. alert->popup_centered();
  125. return;
  126. }
  127. }
  128. hide();
  129. emit_signal("script_created", scr);
  130. }
  131. void ScriptCreateDialog::_load_exist() {
  132. String path = file_path->get_text();
  133. RES p_script = ResourceLoader::load(path, "Script");
  134. if (p_script.is_null()) {
  135. alert->get_ok()->set_text(TTR("OK"));
  136. alert->set_text(vformat(TTR("Error loading script from %s"), path));
  137. alert->popup_centered();
  138. return;
  139. }
  140. hide();
  141. emit_signal("script_created", p_script.get_ref_ptr());
  142. }
  143. void ScriptCreateDialog::_lang_changed(int l) {
  144. l = language_menu->get_selected();
  145. if (ScriptServer::get_language(l)->has_named_classes()) {
  146. has_named_classes = true;
  147. } else {
  148. has_named_classes = false;
  149. }
  150. if (ScriptServer::get_language(l)->can_inherit_from_file()) {
  151. can_inherit_from_file = true;
  152. } else {
  153. can_inherit_from_file = false;
  154. }
  155. String selected_ext = "." + ScriptServer::get_language(l)->get_extension();
  156. String path = file_path->get_text();
  157. String extension = "";
  158. if (path != "") {
  159. if (path.find(".") >= 0) {
  160. extension = path.get_extension();
  161. }
  162. if (extension.length() == 0) {
  163. // add extension if none
  164. path += selected_ext;
  165. _path_changed(path);
  166. } else {
  167. // change extension by selected language
  168. List<String> extensions;
  169. // get all possible extensions for script
  170. for (int l = 0; l < language_menu->get_item_count(); l++) {
  171. ScriptServer::get_language(l)->get_recognized_extensions(&extensions);
  172. }
  173. for (List<String>::Element *E = extensions.front(); E; E = E->next()) {
  174. if (E->get().nocasecmp_to(extension) == 0) {
  175. path = path.get_basename() + selected_ext;
  176. _path_changed(path);
  177. break;
  178. }
  179. }
  180. }
  181. file_path->set_text(path);
  182. }
  183. _update_dialog();
  184. }
  185. void ScriptCreateDialog::_built_in_pressed() {
  186. if (internal->is_pressed()) {
  187. is_built_in = true;
  188. } else {
  189. is_built_in = false;
  190. }
  191. _update_dialog();
  192. }
  193. void ScriptCreateDialog::_browse_path(bool browse_parent) {
  194. is_browsing_parent = browse_parent;
  195. file_browse->set_mode(EditorFileDialog::MODE_SAVE_FILE);
  196. file_browse->set_disable_overwrite_warning(true);
  197. file_browse->clear_filters();
  198. List<String> extensions;
  199. // get all possible extensions for script
  200. for (int l = 0; l < language_menu->get_item_count(); l++) {
  201. ScriptServer::get_language(l)->get_recognized_extensions(&extensions);
  202. }
  203. for (List<String>::Element *E = extensions.front(); E; E = E->next()) {
  204. file_browse->add_filter("*." + E->get());
  205. }
  206. file_browse->set_current_path(file_path->get_text());
  207. file_browse->popup_centered_ratio();
  208. }
  209. void ScriptCreateDialog::_file_selected(const String &p_file) {
  210. String p = GlobalConfig::get_singleton()->localize_path(p_file);
  211. if (is_browsing_parent) {
  212. parent_name->set_text("\"" + p + "\"");
  213. _class_name_changed("\"" + p + "\"");
  214. } else {
  215. file_path->set_text(p);
  216. _path_changed(p);
  217. }
  218. }
  219. void ScriptCreateDialog::_path_changed(const String &p_path) {
  220. is_path_valid = false;
  221. is_new_script_created = true;
  222. String p = p_path;
  223. if (p == "") {
  224. _msg_path_valid(false, TTR("Path is empty"));
  225. _update_dialog();
  226. return;
  227. }
  228. p = GlobalConfig::get_singleton()->localize_path(p);
  229. if (!p.begins_with("res://")) {
  230. _msg_path_valid(false, TTR("Path is not local"));
  231. _update_dialog();
  232. return;
  233. }
  234. if (p.find("/") || p.find("\\")) {
  235. DirAccess *d = DirAccess::create(DirAccess::ACCESS_RESOURCES);
  236. if (d->change_dir(p.get_base_dir()) != OK) {
  237. _msg_path_valid(false, TTR("Invalid base path"));
  238. memdelete(d);
  239. _update_dialog();
  240. return;
  241. }
  242. memdelete(d);
  243. }
  244. /* Does file already exist */
  245. DirAccess *f = DirAccess::create(DirAccess::ACCESS_RESOURCES);
  246. if (f->file_exists(p) && !(f->current_is_dir())) {
  247. is_new_script_created = false;
  248. is_path_valid = true;
  249. }
  250. memdelete(f);
  251. _update_dialog();
  252. /* Check file extension */
  253. String extension = p.get_extension();
  254. List<String> extensions;
  255. // get all possible extensions for script
  256. for (int l = 0; l < language_menu->get_item_count(); l++) {
  257. ScriptServer::get_language(l)->get_recognized_extensions(&extensions);
  258. }
  259. bool found = false;
  260. bool match = false;
  261. int index = 0;
  262. for (List<String>::Element *E = extensions.front(); E; E = E->next()) {
  263. if (E->get().nocasecmp_to(extension) == 0) {
  264. //FIXME (?) - changing language this way doesn't update controls, needs rework
  265. //language_menu->select(index); // change Language option by extension
  266. found = true;
  267. if (E->get() == ScriptServer::get_language(language_menu->get_selected())->get_extension()) {
  268. match = true;
  269. }
  270. break;
  271. }
  272. index++;
  273. }
  274. if (!found) {
  275. _msg_path_valid(false, TTR("Invalid extension"));
  276. _update_dialog();
  277. return;
  278. }
  279. if (!match) {
  280. _msg_path_valid(false, TTR("Wrong extension chosen"));
  281. _update_dialog();
  282. return;
  283. }
  284. /* All checks passed */
  285. is_path_valid = true;
  286. _update_dialog();
  287. }
  288. void ScriptCreateDialog::_msg_script_valid(bool valid, const String &p_msg) {
  289. error_label->set_text(TTR(p_msg));
  290. if (valid) {
  291. error_label->add_color_override("font_color", Color(0, 1.0, 0.8, 0.8));
  292. } else {
  293. error_label->add_color_override("font_color", Color(1, 0.2, 0.2, 0.8));
  294. }
  295. }
  296. void ScriptCreateDialog::_msg_path_valid(bool valid, const String &p_msg) {
  297. path_error_label->set_text(TTR(p_msg));
  298. if (valid) {
  299. path_error_label->add_color_override("font_color", Color(0, 1.0, 0.8, 0.8));
  300. } else {
  301. path_error_label->add_color_override("font_color", Color(1, 0.4, 0.0, 0.8));
  302. }
  303. }
  304. void ScriptCreateDialog::_update_dialog() {
  305. bool script_ok = true;
  306. /* "Add Script Dialog" gui logic and script checks */
  307. // Is Script Valid (order from top to bottom)
  308. get_ok()->set_disabled(true);
  309. if (!is_built_in) {
  310. if (!is_path_valid) {
  311. _msg_script_valid(false, TTR("Invalid Path"));
  312. script_ok = false;
  313. }
  314. }
  315. if (has_named_classes && (!is_class_name_valid)) {
  316. _msg_script_valid(false, TTR("Invalid class name"));
  317. script_ok = false;
  318. }
  319. if (!is_parent_name_valid) {
  320. _msg_script_valid(false, TTR("Invalid inherited parent name or path"));
  321. script_ok = false;
  322. }
  323. if (script_ok) {
  324. _msg_script_valid(true, TTR("Script valid"));
  325. get_ok()->set_disabled(false);
  326. }
  327. /* Does script have named classes */
  328. if (has_named_classes) {
  329. if (is_new_script_created) {
  330. class_name->set_editable(true);
  331. class_name->set_placeholder(TTR("Allowed: a-z, A-Z, 0-9 and _"));
  332. class_name->set_placeholder_alpha(0.3);
  333. } else {
  334. class_name->set_editable(false);
  335. }
  336. } else {
  337. class_name->set_editable(false);
  338. class_name->set_placeholder(TTR("N/A"));
  339. class_name->set_placeholder_alpha(1);
  340. }
  341. /* Can script inherit from a file */
  342. if (can_inherit_from_file) {
  343. parent_browse_button->set_disabled(false);
  344. } else {
  345. parent_browse_button->set_disabled(true);
  346. }
  347. /* Is script Built-in */
  348. if (is_built_in) {
  349. file_path->set_editable(false);
  350. path_button->set_disabled(true);
  351. re_check_path = true;
  352. } else {
  353. file_path->set_editable(true);
  354. path_button->set_disabled(false);
  355. if (re_check_path) {
  356. re_check_path = false;
  357. _path_changed(file_path->get_text());
  358. }
  359. }
  360. /* Is Script created or loaded from existing file */
  361. if (is_new_script_created) {
  362. // New Script Created
  363. get_ok()->set_text(TTR("Create"));
  364. parent_name->set_editable(true);
  365. parent_browse_button->set_disabled(false);
  366. internal->set_disabled(false);
  367. if (is_built_in) {
  368. _msg_path_valid(true, TTR("Built-in script (into scene file)"));
  369. } else {
  370. if (script_ok) {
  371. _msg_path_valid(true, TTR("Create new script file"));
  372. }
  373. }
  374. } else {
  375. // Script Loaded
  376. get_ok()->set_text(TTR("Load"));
  377. parent_name->set_editable(false);
  378. parent_browse_button->set_disabled(true);
  379. internal->set_disabled(true);
  380. if (script_ok) {
  381. _msg_path_valid(true, TTR("Load existing script file"));
  382. }
  383. }
  384. }
  385. void ScriptCreateDialog::_bind_methods() {
  386. ClassDB::bind_method("_class_name_changed", &ScriptCreateDialog::_class_name_changed);
  387. ClassDB::bind_method("_parent_name_changed", &ScriptCreateDialog::_parent_name_changed);
  388. ClassDB::bind_method("_lang_changed", &ScriptCreateDialog::_lang_changed);
  389. ClassDB::bind_method("_built_in_pressed", &ScriptCreateDialog::_built_in_pressed);
  390. ClassDB::bind_method("_browse_path", &ScriptCreateDialog::_browse_path);
  391. ClassDB::bind_method("_file_selected", &ScriptCreateDialog::_file_selected);
  392. ClassDB::bind_method("_path_changed", &ScriptCreateDialog::_path_changed);
  393. ADD_SIGNAL(MethodInfo("script_created", PropertyInfo(Variant::OBJECT, "script", PROPERTY_HINT_RESOURCE_TYPE, "Script")));
  394. }
  395. ScriptCreateDialog::ScriptCreateDialog() {
  396. editor_settings = EditorSettings::get_singleton();
  397. GridContainer *gc = memnew(GridContainer);
  398. VBoxContainer *vb = memnew(VBoxContainer);
  399. HBoxContainer *hb = memnew(HBoxContainer);
  400. Label *l = memnew(Label);
  401. Control *empty = memnew(Control);
  402. Control *empty_h = memnew(Control);
  403. Control *empty_v = memnew(Control);
  404. PanelContainer *pc = memnew(PanelContainer);
  405. /* DIALOG */
  406. /* Main Controls */
  407. gc = memnew(GridContainer);
  408. gc->set_columns(2);
  409. /* Error Stylebox Background */
  410. StyleBoxFlat *sb = memnew(StyleBoxFlat);
  411. sb->set_bg_color(Color(0, 0, 0, 0.05));
  412. sb->set_light_color(Color(1, 1, 1, 0.05));
  413. sb->set_dark_color(Color(1, 1, 1, 0.05));
  414. sb->set_border_blend(false);
  415. sb->set_border_size(1);
  416. sb->set_default_margin(MARGIN_TOP, 10.0 * EDSCALE);
  417. sb->set_default_margin(MARGIN_BOTTOM, 10.0 * EDSCALE);
  418. sb->set_default_margin(MARGIN_LEFT, 10.0 * EDSCALE);
  419. sb->set_default_margin(MARGIN_RIGHT, 10.0 * EDSCALE);
  420. /* Error Messages Field */
  421. vb = memnew(VBoxContainer);
  422. hb = memnew(HBoxContainer);
  423. l = memnew(Label);
  424. l->set_text(" - ");
  425. hb->add_child(l);
  426. error_label = memnew(Label);
  427. error_label->set_text(TTR("Error!"));
  428. error_label->set_align(Label::ALIGN_LEFT);
  429. hb->add_child(error_label);
  430. vb->add_child(hb);
  431. hb = memnew(HBoxContainer);
  432. l = memnew(Label);
  433. l->set_text(" - ");
  434. hb->add_child(l);
  435. path_error_label = memnew(Label);
  436. path_error_label->set_text(TTR("Error!"));
  437. path_error_label->set_align(Label::ALIGN_LEFT);
  438. hb->add_child(path_error_label);
  439. vb->add_child(hb);
  440. pc = memnew(PanelContainer);
  441. pc->set_h_size_flags(Control::SIZE_FILL);
  442. pc->add_style_override("panel", sb);
  443. pc->add_child(vb);
  444. /* Margins */
  445. empty_h = memnew(Control);
  446. empty_h->set_h_size_flags(Control::SIZE_EXPAND_FILL);
  447. empty_h->set_v_size_flags(Control::SIZE_EXPAND_FILL);
  448. empty_h->set_custom_minimum_size(Size2(0, 10 * EDSCALE));
  449. empty_v = memnew(Control);
  450. empty_v->set_h_size_flags(Control::SIZE_EXPAND_FILL);
  451. empty_v->set_v_size_flags(Control::SIZE_EXPAND_FILL);
  452. empty_v->set_custom_minimum_size(Size2(10, 0 * EDSCALE));
  453. vb = memnew(VBoxContainer);
  454. vb->add_child(empty_h->duplicate());
  455. vb->add_child(gc);
  456. vb->add_child(empty_h->duplicate());
  457. vb->add_child(pc);
  458. vb->add_child(empty_h->duplicate());
  459. hb = memnew(HBoxContainer);
  460. hb->add_child(empty_v->duplicate());
  461. hb->add_child(vb);
  462. hb->add_child(empty_v->duplicate());
  463. add_child(hb);
  464. /* Language */
  465. language_menu = memnew(OptionButton);
  466. language_menu->set_custom_minimum_size(Size2(250, 0) * EDSCALE);
  467. language_menu->set_h_size_flags(SIZE_EXPAND_FILL);
  468. l = memnew(Label);
  469. l->set_text(TTR("Language"));
  470. l->set_align(Label::ALIGN_RIGHT);
  471. gc->add_child(l);
  472. gc->add_child(language_menu);
  473. int default_lang = 0;
  474. for (int i = 0; i < ScriptServer::get_language_count(); i++) {
  475. String lang = ScriptServer::get_language(i)->get_name();
  476. language_menu->add_item(lang);
  477. if (lang == "GDScript") {
  478. default_lang = i;
  479. }
  480. }
  481. String last_selected_language = editor_settings->get_project_metadata("script_setup", "last_selected_language", "");
  482. if (last_selected_language != "") {
  483. for (int i = 0; i < language_menu->get_item_count(); i++) {
  484. if (language_menu->get_item_text(i) == last_selected_language) {
  485. language_menu->select(i);
  486. current_language = i;
  487. break;
  488. }
  489. }
  490. } else {
  491. language_menu->select(default_lang);
  492. current_language = default_lang;
  493. }
  494. language_menu->connect("item_selected", this, "_lang_changed");
  495. /* Inherits */
  496. hb = memnew(HBoxContainer);
  497. hb->set_h_size_flags(SIZE_EXPAND_FILL);
  498. parent_name = memnew(LineEdit);
  499. parent_name->connect("text_changed", this, "_parent_name_changed");
  500. parent_name->set_h_size_flags(SIZE_EXPAND_FILL);
  501. hb->add_child(parent_name);
  502. parent_browse_button = memnew(Button);
  503. parent_browse_button->set_flat(true);
  504. parent_browse_button->connect("pressed", this, "_browse_path", varray(true));
  505. hb->add_child(parent_browse_button);
  506. l = memnew(Label);
  507. l->set_text(TTR("Inherits"));
  508. l->set_align(Label::ALIGN_RIGHT);
  509. gc->add_child(l);
  510. gc->add_child(hb);
  511. is_browsing_parent = false;
  512. /* Class Name */
  513. class_name = memnew(LineEdit);
  514. class_name->connect("text_changed", this, "_class_name_changed");
  515. class_name->set_h_size_flags(SIZE_EXPAND_FILL);
  516. l = memnew(Label);
  517. l->set_text(TTR("Class Name"));
  518. l->set_align(Label::ALIGN_RIGHT);
  519. gc->add_child(l);
  520. gc->add_child(class_name);
  521. /* Built-in Script */
  522. internal = memnew(CheckButton);
  523. internal->connect("pressed", this, "_built_in_pressed");
  524. hb = memnew(HBoxContainer);
  525. empty = memnew(Control);
  526. hb->add_child(internal);
  527. hb->add_child(empty);
  528. l = memnew(Label);
  529. l->set_text(TTR("Built-in Script"));
  530. l->set_align(Label::ALIGN_RIGHT);
  531. gc->add_child(l);
  532. gc->add_child(hb);
  533. /* Path */
  534. hb = memnew(HBoxContainer);
  535. file_path = memnew(LineEdit);
  536. file_path->connect("text_changed", this, "_path_changed");
  537. file_path->set_h_size_flags(SIZE_EXPAND_FILL);
  538. hb->add_child(file_path);
  539. path_button = memnew(Button);
  540. path_button->set_flat(true);
  541. path_button->connect("pressed", this, "_browse_path", varray(false));
  542. hb->add_child(path_button);
  543. l = memnew(Label);
  544. l->set_text(TTR("Path"));
  545. l->set_align(Label::ALIGN_RIGHT);
  546. gc->add_child(l);
  547. gc->add_child(hb);
  548. /* Dialog Setup */
  549. file_browse = memnew(EditorFileDialog);
  550. file_browse->connect("file_selected", this, "_file_selected");
  551. add_child(file_browse);
  552. get_ok()->set_text(TTR("Create"));
  553. alert = memnew(AcceptDialog);
  554. alert->set_as_minsize();
  555. alert->get_label()->set_autowrap(true);
  556. alert->get_label()->set_align(Label::ALIGN_CENTER);
  557. alert->get_label()->set_valign(Label::VALIGN_CENTER);
  558. alert->get_label()->set_custom_minimum_size(Size2(325, 60) * EDSCALE);
  559. add_child(alert);
  560. set_as_minsize();
  561. set_hide_on_ok(false);
  562. set_title(TTR("Attach Node Script"));
  563. is_parent_name_valid = false;
  564. is_class_name_valid = false;
  565. is_path_valid = false;
  566. has_named_classes = false;
  567. can_inherit_from_file = false;
  568. is_built_in = false;
  569. is_new_script_created = true;
  570. }