project_settings.cpp 49 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578
  1. /*************************************************************************/
  2. /* project_settings.cpp */
  3. /*************************************************************************/
  4. /* This file is part of: */
  5. /* GODOT ENGINE */
  6. /* http://www.godotengine.org */
  7. /*************************************************************************/
  8. /* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
  9. /* */
  10. /* Permission is hereby granted, free of charge, to any person obtaining */
  11. /* a copy of this software and associated documentation files (the */
  12. /* "Software"), to deal in the Software without restriction, including */
  13. /* without limitation the rights to use, copy, modify, merge, publish, */
  14. /* distribute, sublicense, and/or sell copies of the Software, and to */
  15. /* permit persons to whom the Software is furnished to do so, subject to */
  16. /* the following conditions: */
  17. /* */
  18. /* The above copyright notice and this permission notice shall be */
  19. /* included in all copies or substantial portions of the Software. */
  20. /* */
  21. /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
  22. /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
  23. /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
  24. /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
  25. /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
  26. /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
  27. /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
  28. /*************************************************************************/
  29. #include "project_settings.h"
  30. #include "scene/gui/tab_container.h"
  31. #include "globals.h"
  32. #include "os/keyboard.h"
  33. #include "editor_node.h"
  34. #include "scene/gui/margin_container.h"
  35. #include "translation.h"
  36. ProjectSettings *ProjectSettings::singleton=NULL;
  37. static const char* _button_names[JOY_BUTTON_MAX]={
  38. "PS X, XBox A, NDS B",
  39. "PS Circle, XBox B, NDS A",
  40. "PS Square, XBox X, NDS Y",
  41. "PS Triangle, XBox Y, NDS X",
  42. "L, L1, Wii C",
  43. "R, R1",
  44. "L2, Wii Z",
  45. "R2",
  46. "L3",
  47. "R3",
  48. "Select, Wii -",
  49. "Start, Wii +",
  50. "D-Pad Up",
  51. "D-Pad Down",
  52. "D-Pad Left",
  53. "D-Pad Right"
  54. };
  55. void ProjectSettings::_notification(int p_what) {
  56. if (p_what==NOTIFICATION_ENTER_SCENE) {
  57. translation_list->connect("button_pressed",this,"_translation_delete");
  58. _update_actions();
  59. popup_add->add_icon_item(get_icon("Keyboard","EditorIcons"),"Key",InputEvent::KEY);
  60. popup_add->add_icon_item(get_icon("JoyButton","EditorIcons"),"Joy Button",InputEvent::JOYSTICK_BUTTON);
  61. popup_add->add_icon_item(get_icon("JoyAxis","EditorIcons"),"Joy Axis",InputEvent::JOYSTICK_MOTION);
  62. popup_add->add_icon_item(get_icon("Mouse","EditorIcons"),"Mouse Button",InputEvent::MOUSE_BUTTON);
  63. List<String> tfn;
  64. ResourceLoader::get_recognized_extensions_for_type("Translation",&tfn);
  65. for (List<String>::Element *E=tfn.front();E;E=E->next()) {
  66. translation_file_open->add_filter("*."+E->get());
  67. }
  68. List<String> rfn;
  69. ResourceLoader::get_recognized_extensions_for_type("Resource",&rfn);
  70. for (List<String>::Element *E=rfn.front();E;E=E->next()) {
  71. translation_res_file_open->add_filter("*."+E->get());
  72. translation_res_option_file_open->add_filter("*."+E->get());
  73. }
  74. List<String> afn;
  75. ResourceLoader::get_recognized_extensions_for_type("Script",&afn);
  76. ResourceLoader::get_recognized_extensions_for_type("PackedScene",&afn);
  77. for (List<String>::Element *E=afn.front();E;E=E->next()) {
  78. autoload_file_open->add_filter("*."+E->get());
  79. }
  80. }
  81. }
  82. void ProjectSettings::_action_persist_toggle() {
  83. TreeItem *ti=input_editor->get_selected();
  84. if (!ti)
  85. return;
  86. String name="input/"+ti->get_text(0);
  87. bool prev = Globals::get_singleton()->is_persisting(name);
  88. if (prev==ti->is_checked(0))
  89. return;
  90. setting=true;
  91. undo_redo->create_action("Change Input Action Persistence");
  92. undo_redo->add_do_method(Globals::get_singleton(),"set_persisting",name,ti->is_checked(0));
  93. undo_redo->add_undo_method(Globals::get_singleton(),"set_persisting",name,prev);
  94. undo_redo->add_do_method(this,"_update_actions");
  95. undo_redo->add_undo_method(this,"_update_actions");
  96. undo_redo->add_do_method(this,"_settings_changed");
  97. undo_redo->add_undo_method(this,"_settings_changed");
  98. undo_redo->commit_action();
  99. setting=false;
  100. }
  101. void ProjectSettings::_device_input_add() {
  102. InputEvent ie;
  103. String name=add_at;
  104. Variant old_val = Globals::get_singleton()->get(name);
  105. Array arr=old_val;
  106. ie.device=device_id->get_val();
  107. ie.type=add_type;
  108. switch(add_type) {
  109. case InputEvent::MOUSE_BUTTON: {
  110. ie.mouse_button.button_index=device_index->get_selected()+1;
  111. for(int i=0;i<arr.size();i++) {
  112. InputEvent aie=arr[i];
  113. if (aie.device == ie.device && aie.type==InputEvent::MOUSE_BUTTON && aie.mouse_button.button_index==ie.mouse_button.button_index) {
  114. return;
  115. }
  116. }
  117. } break;
  118. case InputEvent::JOYSTICK_MOTION: {
  119. ie.joy_motion.axis = device_index->get_selected();
  120. for(int i=0;i<arr.size();i++) {
  121. InputEvent aie=arr[i];
  122. if (aie.device == ie.device && aie.type==InputEvent::JOYSTICK_MOTION && aie.joy_motion.axis==ie.joy_motion.axis) {
  123. return;
  124. }
  125. }
  126. } break;
  127. case InputEvent::JOYSTICK_BUTTON: {
  128. ie.joy_button.button_index=device_index->get_selected();
  129. for(int i=0;i<arr.size();i++) {
  130. InputEvent aie=arr[i];
  131. if (aie.device == ie.device && aie.type==InputEvent::JOYSTICK_BUTTON && aie.joy_button.button_index==ie.joy_button.button_index) {
  132. return;
  133. }
  134. }
  135. } break;
  136. default:{}
  137. }
  138. arr.push_back(ie);
  139. undo_redo->create_action("Add Input Action Event");
  140. undo_redo->add_do_method(Globals::get_singleton(),"set",name,arr);
  141. undo_redo->add_do_method(Globals::get_singleton(),"set_persisting",name,true);
  142. undo_redo->add_undo_method(Globals::get_singleton(),"set",name,old_val);
  143. undo_redo->add_do_method(this,"_update_actions");
  144. undo_redo->add_undo_method(this,"_update_actions");
  145. undo_redo->add_do_method(this,"_settings_changed");
  146. undo_redo->add_undo_method(this,"_settings_changed");
  147. undo_redo->commit_action();
  148. }
  149. void ProjectSettings::_press_a_key_confirm() {
  150. if (last_wait_for_key.type!=InputEvent::KEY)
  151. return;
  152. InputEvent ie;
  153. ie.type=InputEvent::KEY;
  154. ie.key.scancode=last_wait_for_key.key.scancode;
  155. ie.key.mod=last_wait_for_key.key.mod;
  156. String name=add_at;
  157. Variant old_val = Globals::get_singleton()->get(name);
  158. Array arr=old_val;
  159. for(int i=0;i<arr.size();i++) {
  160. InputEvent aie=arr[i];
  161. if (aie.type==InputEvent::KEY && aie.key.scancode==ie.key.scancode && aie.key.mod==ie.key.mod) {
  162. return;
  163. }
  164. }
  165. arr.push_back(ie);
  166. undo_redo->create_action("Add Input Action Event");
  167. undo_redo->add_do_method(Globals::get_singleton(),"set",name,arr);
  168. undo_redo->add_do_method(Globals::get_singleton(),"set_persisting",name,true);
  169. undo_redo->add_undo_method(Globals::get_singleton(),"set",name,old_val);
  170. undo_redo->add_do_method(this,"_update_actions");
  171. undo_redo->add_undo_method(this,"_update_actions");
  172. undo_redo->add_do_method(this,"_settings_changed");
  173. undo_redo->add_undo_method(this,"_settings_changed");
  174. undo_redo->commit_action();
  175. }
  176. void ProjectSettings::_wait_for_key(const InputEvent& p_event) {
  177. if (p_event.type==InputEvent::KEY && p_event.key.pressed && p_event.key.scancode!=0) {
  178. last_wait_for_key=p_event;
  179. String str=keycode_get_string(p_event.key.scancode).capitalize();
  180. if (p_event.key.mod.meta)
  181. str="Meta+"+str;
  182. if (p_event.key.mod.shift)
  183. str="Shift+"+str;
  184. if (p_event.key.mod.alt)
  185. str="Alt+"+str;
  186. if (p_event.key.mod.control)
  187. str="Control+"+str;
  188. press_a_key_label->set_text(str);
  189. press_a_key->accept_event();
  190. }
  191. }
  192. void ProjectSettings::_add_item(int p_item){
  193. add_type=InputEvent::Type(p_item);
  194. switch(add_type) {
  195. case InputEvent::KEY: {
  196. press_a_key_label->set_text("Press a Key..");
  197. last_wait_for_key=InputEvent();
  198. press_a_key->popup_centered(Size2(250,80));
  199. press_a_key->grab_focus();
  200. } break;
  201. case InputEvent::MOUSE_BUTTON: {
  202. device_id->set_val(0);
  203. device_index_label->set_text("Mouse Button Index:");
  204. device_index->clear();
  205. device_index->add_item("Left Button");
  206. device_index->add_item("Right Button");
  207. device_index->add_item("Middle Button");
  208. device_index->add_item("Wheel Up Button");
  209. device_index->add_item("Wheel Down Button");
  210. device_index->add_item("Button 6");
  211. device_index->add_item("Button 7");
  212. device_index->add_item("Button 8");
  213. device_index->add_item("Button 9");
  214. device_input->popup_centered(Size2(350,95));
  215. } break;
  216. case InputEvent::JOYSTICK_MOTION: {
  217. device_id->set_val(0);
  218. device_index_label->set_text("Joy Button Axis:");
  219. device_index->clear();
  220. for(int i=0;i<8;i++) {
  221. device_index->add_item("Axis "+itos(i));
  222. }
  223. device_input->popup_centered(Size2(350,95));
  224. } break;
  225. case InputEvent::JOYSTICK_BUTTON: {
  226. device_id->set_val(0);
  227. device_index_label->set_text("Joy Button Index:");
  228. device_index->clear();
  229. for(int i=0;i<JOY_BUTTON_MAX;i++) {
  230. device_index->add_item(String(_button_names[i]));
  231. }
  232. device_input->popup_centered(Size2(350,95));
  233. } break;
  234. default:{}
  235. }
  236. }
  237. void ProjectSettings::_action_button_pressed(Object* p_obj, int p_column,int p_id) {
  238. TreeItem *ti=p_obj->cast_to<TreeItem>();
  239. ERR_FAIL_COND(!ti);
  240. if (p_id==1) {
  241. Point2 ofs = input_editor->get_global_pos();
  242. Rect2 ir=input_editor->get_item_rect(ti);
  243. ir.pos.y-=input_editor->get_scroll().y;
  244. ofs+=ir.pos+ir.size;
  245. ofs.x-=100;
  246. popup_add->set_pos(ofs);
  247. popup_add->popup();
  248. add_at="input/"+ti->get_text(0);
  249. } else if (p_id==2) {
  250. //remove
  251. if (ti->get_parent()==input_editor->get_root()) {
  252. //remove main thing
  253. String name="input/"+ti->get_text(0);
  254. Variant old_val = Globals::get_singleton()->get(name);
  255. int order=Globals::get_singleton()->get_order(name);
  256. undo_redo->create_action("Add Input Action");
  257. undo_redo->add_do_method(Globals::get_singleton(),"clear",name);
  258. undo_redo->add_undo_method(Globals::get_singleton(),"set",name,old_val);
  259. undo_redo->add_undo_method(Globals::get_singleton(),"set_order",name,order);
  260. undo_redo->add_undo_method(Globals::get_singleton(),"set_persisting",name,Globals::get_singleton()->is_persisting(name));
  261. undo_redo->add_do_method(this,"_update_actions");
  262. undo_redo->add_undo_method(this,"_update_actions");
  263. undo_redo->add_do_method(this,"_settings_changed");
  264. undo_redo->add_undo_method(this,"_settings_changed");
  265. undo_redo->commit_action();
  266. } else {
  267. //remove action
  268. String name="input/"+ti->get_parent()->get_text(0);
  269. Variant old_val = Globals::get_singleton()->get(name);
  270. int idx = ti->get_metadata(0);
  271. Array va = old_val;
  272. ERR_FAIL_INDEX(idx,va.size());
  273. for(int i=idx;i<va.size()-1;i++) {
  274. va[i]=va[i+1];
  275. }
  276. va.resize(va.size()-1);
  277. undo_redo->create_action("Erase Input Action Event");
  278. undo_redo->add_do_method(Globals::get_singleton(),"set",name,va);
  279. undo_redo->add_undo_method(Globals::get_singleton(),"set",name,old_val);
  280. undo_redo->add_do_method(this,"_update_actions");
  281. undo_redo->add_undo_method(this,"_update_actions");
  282. undo_redo->add_do_method(this,"_settings_changed");
  283. undo_redo->add_undo_method(this,"_settings_changed");
  284. undo_redo->commit_action();
  285. }
  286. }
  287. }
  288. void ProjectSettings::_update_actions() {
  289. if (setting)
  290. return;
  291. input_editor->clear();
  292. TreeItem *root = input_editor->create_item();
  293. input_editor->set_hide_root(true);
  294. List<PropertyInfo> props;
  295. Globals::get_singleton()->get_property_list(&props);
  296. for(List<PropertyInfo>::Element *E=props.front();E;E=E->next()) {
  297. const PropertyInfo &pi=E->get();
  298. if (!pi.name.begins_with("input/"))
  299. continue;
  300. String name = pi.name.get_slice("/",1);
  301. if (name=="")
  302. continue;
  303. TreeItem *item=input_editor->create_item(root);
  304. item->set_cell_mode(0,TreeItem::CELL_MODE_CHECK);
  305. item->set_text(0,name);
  306. item->add_button(0,get_icon("Add","EditorIcons"),1);
  307. item->add_button(0,get_icon("Del","EditorIcons"),2);
  308. item->set_custom_bg_color(0,get_color("prop_subsection","Editor"));
  309. item->set_editable(0,true);
  310. item->set_checked(0,pi.usage&PROPERTY_USAGE_CHECKED);
  311. Array actions=Globals::get_singleton()->get(pi.name);
  312. for(int i=0;i<actions.size();i++) {
  313. if (actions[i].get_type()!=Variant::INPUT_EVENT)
  314. continue;
  315. InputEvent ie = actions[i];
  316. TreeItem *action = input_editor->create_item(item);
  317. switch(ie.type) {
  318. case InputEvent::KEY: {
  319. String str=keycode_get_string(ie.key.scancode).capitalize();
  320. if (ie.key.mod.meta)
  321. str="Meta+"+str;
  322. if (ie.key.mod.shift)
  323. str="Shift+"+str;
  324. if (ie.key.mod.alt)
  325. str="Alt+"+str;
  326. if (ie.key.mod.control)
  327. str="Control+"+str;
  328. action->set_text(0,str);
  329. action->set_icon(0,get_icon("Keyboard","EditorIcons"));
  330. } break;
  331. case InputEvent::JOYSTICK_BUTTON: {
  332. String str = "Device "+itos(ie.device)+", Button "+itos(ie.joy_button.button_index);
  333. if (ie.joy_button.button_index>=0 && ie.joy_button.button_index<14)
  334. str+=String()+" ("+_button_names[ie.joy_button.button_index]+").";
  335. else
  336. str+=".";
  337. action->set_text(0,str);
  338. action->set_icon(0,get_icon("JoyButton","EditorIcons"));
  339. } break;
  340. case InputEvent::MOUSE_BUTTON: {
  341. String str = "Device "+itos(ie.device)+", ";
  342. switch (ie.mouse_button.button_index) {
  343. case BUTTON_LEFT: str+="Left Button."; break;
  344. case BUTTON_RIGHT: str+="Right Button."; break;
  345. case BUTTON_MIDDLE: str+="Middle Button."; break;
  346. case BUTTON_WHEEL_UP: str+="Wheel Up."; break;
  347. case BUTTON_WHEEL_DOWN: str+="Wheel Down."; break;
  348. default: str+="Button "+itos(ie.mouse_button.button_index)+".";
  349. }
  350. action->set_text(0,str);
  351. action->set_icon(0,get_icon("Mouse","EditorIcons"));
  352. } break;
  353. case InputEvent::JOYSTICK_MOTION: {
  354. String str = "Device "+itos(ie.device)+", Axis "+itos(ie.joy_motion.axis)+".";
  355. action->set_text(0,str);
  356. action->set_icon(0,get_icon("JoyAxis","EditorIcons"));
  357. } break;
  358. }
  359. action->add_button(0,get_icon("Del","EditorIcons"),2);
  360. action->set_metadata(0,i);
  361. }
  362. }
  363. }
  364. void ProjectSettings::popup_project_settings() {
  365. //popup_centered(Size2(500,400));
  366. popup_centered_ratio();
  367. globals_editor->edit(NULL);
  368. globals_editor->edit(Globals::get_singleton());
  369. _update_translations();
  370. _update_autoload();
  371. }
  372. void ProjectSettings::_item_selected() {
  373. TreeItem *ti = globals_editor->get_tree()->get_selected();
  374. if (!ti)
  375. return;
  376. if (!ti->get_parent())
  377. return;
  378. category->set_text(ti->get_parent()->get_text(0));
  379. property->set_text(ti->get_text(0));
  380. popup_platform->set_disabled(false);
  381. }
  382. void ProjectSettings::_item_adds(String) {
  383. _item_add();
  384. }
  385. void ProjectSettings::_item_add() {
  386. Variant value;
  387. switch(type->get_selected()) {
  388. case 0: value=false; break;
  389. case 1: value=0; break;
  390. case 2: value=0.0; break;
  391. case 3: value=""; break;
  392. }
  393. String catname = category->get_text();
  394. /*if (!catname.is_valid_identifier()) {
  395. message->set_text("Invalid Category.\nValid characters: a-z,A-Z,0-9 or _");
  396. message->popup_centered(Size2(300,100));
  397. return;
  398. }*/
  399. String propname = property->get_text();
  400. /*if (!propname.is_valid_identifier()) {
  401. message->set_text("Invalid Property.\nValid characters: a-z,A-Z,0-9 or _");
  402. message->popup_centered(Size2(300,100));
  403. return;
  404. }*/
  405. String name = catname+"/"+propname;
  406. Globals::get_singleton()->set(name,value);
  407. globals_editor->update_tree();
  408. }
  409. void ProjectSettings::_item_del() {
  410. String catname = category->get_text();
  411. //ERR_FAIL_COND(!catname.is_valid_identifier());
  412. String propname = property->get_text();
  413. //ERR_FAIL_COND(!propname.is_valid_identifier());
  414. String name = catname+"/"+propname;
  415. Globals::get_singleton()->set(name,Variant());
  416. globals_editor->update_tree();
  417. }
  418. void ProjectSettings::_action_adds(String) {
  419. _action_add();
  420. }
  421. void ProjectSettings::_action_add() {
  422. String action = action_name->get_text();
  423. if (action.find("/")!=-1 || action.find(":")!=-1 || action=="") {
  424. message->set_text("Invalid Action (Anything goes but / or :).");
  425. message->popup_centered(Size2(300,100));
  426. return;
  427. }
  428. if (Globals::get_singleton()->has("input/"+action)) {
  429. message->set_text("Action '"+action+"' already exists!.");
  430. message->popup_centered(Size2(300,100));
  431. return;
  432. }
  433. Array va;
  434. String name = "input/"+action;
  435. undo_redo->create_action("Add Input Action Event");
  436. undo_redo->add_do_method(Globals::get_singleton(),"set",name,va);
  437. undo_redo->add_do_method(Globals::get_singleton(),"set_persisting",name,true);
  438. undo_redo->add_undo_method(Globals::get_singleton(),"clear",name);
  439. undo_redo->add_do_method(this,"_update_actions");
  440. undo_redo->add_undo_method(this,"_update_actions");
  441. undo_redo->add_do_method(this,"_settings_changed");
  442. undo_redo->add_undo_method(this,"_settings_changed");
  443. undo_redo->commit_action();
  444. TreeItem *r = input_editor->get_root();
  445. if (!r)
  446. return;
  447. r=r->get_children();
  448. if (!r)
  449. return;
  450. while(r->get_next())
  451. r=r->get_next();
  452. if (!r)
  453. return;
  454. r->select(0);
  455. input_editor->ensure_cursor_is_visible();
  456. }
  457. void ProjectSettings::_item_checked(const String& p_item, bool p_check) {
  458. undo_redo->create_action("Toggle Persisting");
  459. undo_redo->add_do_method(Globals::get_singleton(),"set_persisting",p_item,p_check);
  460. undo_redo->add_undo_method(Globals::get_singleton(),"set_persisting",p_item,!p_check);
  461. undo_redo->add_do_method(this,"_settings_changed");
  462. undo_redo->add_undo_method(this,"_settings_changed");
  463. undo_redo->commit_action();
  464. }
  465. void ProjectSettings::_save() {
  466. Error err = Globals::get_singleton()->save();
  467. message->set_text(err!=OK?"Error saving settings.":"Settings Saved OK.");
  468. message->popup_centered(Size2(300,100));
  469. }
  470. void ProjectSettings::_settings_prop_edited(const String& p_name) {
  471. if (!Globals::get_singleton()->is_persisting(p_name)) {
  472. Globals::get_singleton()->set_persisting(p_name,true);
  473. // globals_editor->update_property(p_name);
  474. globals_editor->update_tree();
  475. }
  476. _settings_changed();
  477. }
  478. void ProjectSettings::_settings_changed() {
  479. timer->start();
  480. }
  481. void ProjectSettings::_copy_to_platform(int p_which) {
  482. String catname = category->get_text();
  483. if (!catname.is_valid_identifier()) {
  484. message->set_text("Invalid Category.\nValid characters: a-z,A-Z,0-9 or _");
  485. message->popup_centered(Size2(300,100));
  486. return;
  487. }
  488. String propname = property->get_text();
  489. if (!propname.is_valid_identifier()) {
  490. message->set_text("Invalid Property.\nValid characters: a-z,A-Z,0-9 or _");
  491. message->popup_centered(Size2(300,100));
  492. return;
  493. }
  494. String name = catname+"/"+propname;
  495. Variant value=Globals::get_singleton()->get(name);
  496. catname+="."+popup_platform->get_popup()->get_item_text(p_which);;
  497. name = catname+"/"+propname;
  498. Globals::get_singleton()->set(name,value);
  499. globals_editor->update_tree();
  500. }
  501. void ProjectSettings::add_translation(const String& p_translation) {
  502. _translation_add(p_translation);
  503. }
  504. void ProjectSettings::_translation_add(const String& p_path) {
  505. StringArray translations = Globals::get_singleton()->get("locale/translations");
  506. for(int i=0;i<translations.size();i++) {
  507. if (translations[i]==p_path)
  508. return; //exists
  509. }
  510. translations.push_back(p_path);
  511. undo_redo->create_action("Add Translation");
  512. undo_redo->add_do_property(Globals::get_singleton(),"locale/translations",translations);
  513. undo_redo->add_undo_property(Globals::get_singleton(),"locale/translations",Globals::get_singleton()->get("locale/translations"));
  514. undo_redo->add_do_method(Globals::get_singleton(),"set_persisting","locale/translations",true);
  515. undo_redo->add_do_method(this,"_update_translations");
  516. undo_redo->add_undo_method(this,"_update_translations");
  517. undo_redo->add_do_method(this,"_settings_changed");
  518. undo_redo->add_undo_method(this,"_settings_changed");
  519. undo_redo->commit_action();
  520. }
  521. void ProjectSettings::_translation_file_open() {
  522. translation_file_open->popup_centered_ratio();
  523. }
  524. void ProjectSettings::_autoload_file_callback(const String& p_path) {
  525. autoload_add_path->set_text(p_path);
  526. //_translation_add(p_translation);
  527. }
  528. void ProjectSettings::_autoload_file_open() {
  529. autoload_file_open->popup_centered_ratio();
  530. }
  531. void ProjectSettings::_autoload_add() {
  532. String name = autoload_add_name->get_text();
  533. if (!name.is_valid_identifier()) {
  534. message->set_text("Invalid Name.\nValid characters: a-z,A-Z,0-9 or _");
  535. message->popup_centered(Size2(300,100));
  536. return;
  537. }
  538. String path = autoload_add_path->get_text();
  539. if (!FileAccess::exists(path)) {
  540. message->set_text("Invalid Path.\nFile does not exist.");
  541. message->popup_centered(Size2(300,100));
  542. return;
  543. }
  544. if (!path.begins_with("res://")) {
  545. message->set_text("Invalid Path.\nNot in resource path.");
  546. message->popup_centered(Size2(300,100));
  547. return;
  548. }
  549. undo_redo->create_action("Add Autoload");
  550. name = "autoload/"+name;
  551. undo_redo->add_do_property(Globals::get_singleton(),name,path);
  552. if (Globals::get_singleton()->has(name))
  553. undo_redo->add_undo_property(Globals::get_singleton(),name,Globals::get_singleton()->get(name));
  554. else
  555. undo_redo->add_undo_property(Globals::get_singleton(),name,Variant());
  556. undo_redo->add_do_method(Globals::get_singleton(),"set_persisting",name,true);
  557. undo_redo->add_do_method(this,"_update_autoload");
  558. undo_redo->add_undo_method(this,"_update_autoload");
  559. undo_redo->add_do_method(this,"_settings_changed");
  560. undo_redo->add_undo_method(this,"_settings_changed");
  561. undo_redo->commit_action();
  562. //autoload_file_open->popup_centered_ratio();
  563. }
  564. void ProjectSettings::_autoload_delete(Object *p_item,int p_column, int p_button) {
  565. TreeItem *ti=p_item->cast_to<TreeItem>();
  566. String name = "autoload/"+ti->get_text(0);
  567. undo_redo->create_action("Remove Autoload");
  568. undo_redo->add_do_property(Globals::get_singleton(),name,Variant());
  569. undo_redo->add_undo_property(Globals::get_singleton(),name,Globals::get_singleton()->get(name));
  570. undo_redo->add_undo_method(Globals::get_singleton(),"set_persisting",name,true);
  571. undo_redo->add_do_method(this,"_update_autoload");
  572. undo_redo->add_undo_method(this,"_update_autoload");
  573. undo_redo->add_do_method(this,"_settings_changed");
  574. undo_redo->add_undo_method(this,"_settings_changed");
  575. undo_redo->commit_action();
  576. }
  577. void ProjectSettings::_translation_delete(Object *p_item,int p_column, int p_button) {
  578. TreeItem *ti = p_item->cast_to<TreeItem>();
  579. ERR_FAIL_COND(!ti);
  580. int idx=ti->get_metadata(0);
  581. StringArray translations = Globals::get_singleton()->get("locale/translations");
  582. ERR_FAIL_INDEX(idx,translations.size());
  583. translations.remove(idx);
  584. undo_redo->create_action("Remove Translation");
  585. undo_redo->add_do_property(Globals::get_singleton(),"locale/translations",translations);
  586. undo_redo->add_undo_property(Globals::get_singleton(),"locale/translations",Globals::get_singleton()->get("locale/translations"));
  587. undo_redo->add_do_method(this,"_update_translations");
  588. undo_redo->add_undo_method(this,"_update_translations");
  589. undo_redo->add_do_method(this,"_settings_changed");
  590. undo_redo->add_undo_method(this,"_settings_changed");
  591. undo_redo->commit_action();
  592. }
  593. void ProjectSettings::_translation_res_file_open() {
  594. translation_res_file_open->popup_centered_ratio();
  595. }
  596. void ProjectSettings::_translation_res_add(const String& p_path){
  597. Variant prev;
  598. Dictionary remaps;
  599. if (Globals::get_singleton()->has("locale/translation_remaps")) {
  600. remaps = Globals::get_singleton()->get("locale/translation_remaps");
  601. prev=remaps;
  602. }
  603. if (remaps.has(p_path))
  604. return; //pointless already has it
  605. remaps[p_path]=StringArray();
  606. undo_redo->create_action("Add Remapped Path");
  607. undo_redo->add_do_property(Globals::get_singleton(),"locale/translation_remaps",remaps);
  608. undo_redo->add_do_method(Globals::get_singleton(),"set_persisting","locale/translation_remaps",true);
  609. undo_redo->add_undo_property(Globals::get_singleton(),"locale/translation_remaps",prev);
  610. undo_redo->add_do_method(this,"_update_translations");
  611. undo_redo->add_undo_method(this,"_update_translations");
  612. undo_redo->add_do_method(this,"_settings_changed");
  613. undo_redo->add_undo_method(this,"_settings_changed");
  614. undo_redo->commit_action();
  615. }
  616. void ProjectSettings::_translation_res_option_file_open(){
  617. translation_res_option_file_open->popup_centered_ratio();
  618. }
  619. void ProjectSettings::_translation_res_option_add(const String& p_path) {
  620. ERR_FAIL_COND(!Globals::get_singleton()->has("locale/translation_remaps"));
  621. Dictionary remaps = Globals::get_singleton()->get("locale/translation_remaps");
  622. TreeItem *k = translation_remap->get_selected();
  623. ERR_FAIL_COND(!k);
  624. String key = k->get_metadata(0);
  625. ERR_FAIL_COND(!remaps.has(key));
  626. StringArray r = remaps[key];
  627. r.push_back(p_path+":"+"en");
  628. remaps[key]=r;
  629. undo_redo->create_action("Resource Remap Add Remap");
  630. undo_redo->add_do_property(Globals::get_singleton(),"locale/translation_remaps",remaps);
  631. undo_redo->add_do_method(Globals::get_singleton(),"set_persisting","locale/translation_remaps",true);
  632. undo_redo->add_undo_property(Globals::get_singleton(),"locale/translation_remaps",Globals::get_singleton()->get("locale/translation_remaps"));
  633. undo_redo->add_do_method(this,"_update_translations");
  634. undo_redo->add_undo_method(this,"_update_translations");
  635. undo_redo->add_do_method(this,"_settings_changed");
  636. undo_redo->add_undo_method(this,"_settings_changed");
  637. undo_redo->commit_action();
  638. }
  639. void ProjectSettings::_translation_res_select() {
  640. if (updating_translations)
  641. return;
  642. call_deferred("_update_translations");
  643. }
  644. void ProjectSettings::_translation_res_option_changed() {
  645. if (updating_translations)
  646. return;
  647. if (!Globals::get_singleton()->has("locale/translation_remaps"))
  648. return;
  649. Dictionary remaps = Globals::get_singleton()->get("locale/translation_remaps");
  650. TreeItem *k = translation_remap->get_selected();
  651. ERR_FAIL_COND(!k);
  652. TreeItem *ed = translation_remap_options->get_edited();
  653. ERR_FAIL_COND(!ed);
  654. String key = k->get_metadata(0);
  655. int idx = ed->get_metadata(0);
  656. String path = ed->get_metadata(1);
  657. int which = ed->get_range(1);
  658. Vector<String> langs = TranslationServer::get_all_locales();
  659. ERR_FAIL_INDEX(which,langs.size());
  660. ERR_FAIL_COND(!remaps.has(key));
  661. StringArray r = remaps[key];
  662. ERR_FAIL_INDEX(idx,remaps.size());
  663. r.set(idx,path+":"+langs[which]);
  664. remaps[key]=r;
  665. updating_translations=true;
  666. undo_redo->create_action("Change Resource Remap Language");
  667. undo_redo->add_do_property(Globals::get_singleton(),"locale/translation_remaps",remaps);
  668. undo_redo->add_do_method(Globals::get_singleton(),"set_persisting","locale/translation_remaps",true);
  669. undo_redo->add_undo_property(Globals::get_singleton(),"locale/translation_remaps",Globals::get_singleton()->get("locale/translation_remaps"));
  670. undo_redo->add_do_method(this,"_update_translations");
  671. undo_redo->add_undo_method(this,"_update_translations");
  672. undo_redo->add_do_method(this,"_settings_changed");
  673. undo_redo->add_undo_method(this,"_settings_changed");
  674. undo_redo->commit_action();
  675. updating_translations=false;
  676. }
  677. void ProjectSettings::_translation_res_delete(Object *p_item,int p_column, int p_button) {
  678. if (updating_translations)
  679. return;
  680. if (!Globals::get_singleton()->has("locale/translation_remaps"))
  681. return;
  682. Dictionary remaps = Globals::get_singleton()->get("locale/translation_remaps");
  683. TreeItem *k = p_item->cast_to<TreeItem>();
  684. String key = k->get_metadata(0);
  685. ERR_FAIL_COND(!remaps.has(key));
  686. remaps.erase(key);
  687. undo_redo->create_action("Remove Resource Remap");
  688. undo_redo->add_do_property(Globals::get_singleton(),"locale/translation_remaps",remaps);
  689. undo_redo->add_do_method(Globals::get_singleton(),"set_persisting","locale/translation_remaps",true);
  690. undo_redo->add_undo_property(Globals::get_singleton(),"locale/translation_remaps",Globals::get_singleton()->get("locale/translation_remaps"));
  691. undo_redo->add_do_method(this,"_update_translations");
  692. undo_redo->add_undo_method(this,"_update_translations");
  693. undo_redo->add_do_method(this,"_settings_changed");
  694. undo_redo->add_undo_method(this,"_settings_changed");
  695. undo_redo->commit_action();
  696. }
  697. void ProjectSettings::_translation_res_option_delete(Object *p_item,int p_column, int p_button) {
  698. if (updating_translations)
  699. return;
  700. if (!Globals::get_singleton()->has("locale/translation_remaps"))
  701. return;
  702. Dictionary remaps = Globals::get_singleton()->get("locale/translation_remaps");
  703. TreeItem *k = translation_remap->get_selected();
  704. ERR_FAIL_COND(!k);
  705. TreeItem *ed = p_item->cast_to<TreeItem>();
  706. ERR_FAIL_COND(!ed);
  707. String key = k->get_metadata(0);
  708. int idx = ed->get_metadata(0);
  709. ERR_FAIL_COND(!remaps.has(key));
  710. StringArray r = remaps[key];
  711. ERR_FAIL_INDEX(idx,remaps.size());
  712. r.remove(idx);
  713. remaps[key]=r;
  714. undo_redo->create_action("Remove Resource Remap Option");
  715. undo_redo->add_do_property(Globals::get_singleton(),"locale/translation_remaps",remaps);
  716. undo_redo->add_do_method(Globals::get_singleton(),"set_persisting","locale/translation_remaps",true);
  717. undo_redo->add_undo_property(Globals::get_singleton(),"locale/translation_remaps",Globals::get_singleton()->get("locale/translation_remaps"));
  718. undo_redo->add_do_method(this,"_update_translations");
  719. undo_redo->add_undo_method(this,"_update_translations");
  720. undo_redo->add_do_method(this,"_settings_changed");
  721. undo_redo->add_undo_method(this,"_settings_changed");
  722. undo_redo->commit_action();
  723. }
  724. void ProjectSettings::_update_translations() {
  725. //update translations
  726. if (updating_translations)
  727. return;
  728. updating_translations=true;
  729. translation_list->clear();
  730. TreeItem *root = translation_list->create_item(NULL);
  731. translation_list->set_hide_root(true);
  732. if (Globals::get_singleton()->has("locale/translations")) {
  733. StringArray translations = Globals::get_singleton()->get("locale/translations");
  734. for(int i=0;i<translations.size();i++) {
  735. TreeItem *t = translation_list->create_item(root);
  736. t->set_editable(0,false);
  737. t->set_text(0,translations[i].replace_first("res://",""));
  738. t->set_tooltip(0,translations[i]);
  739. t->set_metadata(0,i);
  740. t->add_button(0,get_icon("Del","EditorIcons"),0);
  741. }
  742. }
  743. //update translation remaps
  744. String remap_selected;
  745. if (translation_remap->get_selected()) {
  746. remap_selected = translation_remap->get_selected()->get_metadata(0);
  747. }
  748. translation_remap->clear();
  749. translation_remap_options->clear();
  750. root = translation_remap->create_item(NULL);
  751. TreeItem *root2 = translation_remap_options->create_item(NULL);
  752. translation_remap->set_hide_root(true);
  753. translation_remap_options->set_hide_root(true);
  754. translation_res_option_add_button->set_disabled(true);
  755. Vector<String> langs = TranslationServer::get_all_locales();
  756. Vector<String> names = TranslationServer::get_all_locale_names();
  757. String langnames;
  758. for(int i=0;i<names.size();i++) {
  759. if (i>0)
  760. langnames+=",";
  761. langnames+=names[i];
  762. }
  763. if (Globals::get_singleton()->has("locale/translation_remaps")) {
  764. Dictionary remaps = Globals::get_singleton()->get("locale/translation_remaps");
  765. List<Variant> rk;
  766. remaps.get_key_list(&rk);
  767. Vector<String> keys;
  768. for(List<Variant>::Element *E=rk.front();E;E=E->next()) {
  769. keys.push_back(E->get());
  770. }
  771. keys.sort();
  772. for(int i=0;i<keys.size();i++) {
  773. TreeItem *t = translation_remap->create_item(root);
  774. t->set_editable(0,false);
  775. t->set_text(0,keys[i].replace_first("res://",""));
  776. t->set_tooltip(0,keys[i]);
  777. t->set_metadata(0,keys[i]);
  778. t->add_button(0,get_icon("Del","EditorIcons"),0);
  779. if (keys[i]==remap_selected) {
  780. t->select(0);
  781. translation_res_option_add_button->set_disabled(false);
  782. StringArray selected = remaps[keys[i]];
  783. for(int j=0;j<selected.size();j++) {
  784. String s = selected[j];
  785. int qp = s.find_last(":");
  786. String path = s.substr(0,qp);
  787. String locale = s.substr(qp+1,s.length());
  788. TreeItem *t2 = translation_remap_options->create_item(root2);
  789. t2->set_editable(0,false);
  790. t2->set_text(0,path.replace_first("res://",""));
  791. t2->set_tooltip(0,path);
  792. t2->set_metadata(0,j);
  793. t2->add_button(0,get_icon("Del","EditorIcons"),0);
  794. t2->set_cell_mode(1,TreeItem::CELL_MODE_RANGE);
  795. t2->set_text(1,langnames);
  796. t2->set_editable(1,true);
  797. t2->set_metadata(1,path);
  798. int idx = langs.find(locale);
  799. if (idx<0)
  800. idx=0;
  801. t2->set_range(1,idx);
  802. }
  803. }
  804. }
  805. }
  806. updating_translations=false;
  807. }
  808. void ProjectSettings::_update_autoload() {
  809. autoload_list->clear();
  810. TreeItem *root = autoload_list->create_item();
  811. autoload_list->set_hide_root(true);
  812. List<PropertyInfo> props;
  813. Globals::get_singleton()->get_property_list(&props);
  814. for(List<PropertyInfo>::Element *E=props.front();E;E=E->next()) {
  815. const PropertyInfo &pi=E->get();
  816. if (!pi.name.begins_with("autoload/"))
  817. continue;
  818. String name = pi.name.get_slice("/",1);
  819. if (name=="")
  820. continue;
  821. TreeItem *t = autoload_list->create_item(root);
  822. t->set_text(0,name);
  823. t->set_text(1,Globals::get_singleton()->get(pi.name));
  824. t->add_button(1,get_icon("Del","EditorIcons"),0);
  825. }
  826. }
  827. void ProjectSettings::_bind_methods() {
  828. ObjectTypeDB::bind_method(_MD("_item_selected"),&ProjectSettings::_item_selected);
  829. ObjectTypeDB::bind_method(_MD("_item_add"),&ProjectSettings::_item_add);
  830. ObjectTypeDB::bind_method(_MD("_item_adds"),&ProjectSettings::_item_adds);
  831. ObjectTypeDB::bind_method(_MD("_item_del"),&ProjectSettings::_item_del);
  832. ObjectTypeDB::bind_method(_MD("_item_checked"),&ProjectSettings::_item_checked);
  833. ObjectTypeDB::bind_method(_MD("_save"),&ProjectSettings::_save);
  834. ObjectTypeDB::bind_method(_MD("_action_add"),&ProjectSettings::_action_add);
  835. ObjectTypeDB::bind_method(_MD("_action_adds"),&ProjectSettings::_action_adds);
  836. ObjectTypeDB::bind_method(_MD("_action_persist_toggle"),&ProjectSettings::_action_persist_toggle);
  837. ObjectTypeDB::bind_method(_MD("_action_button_pressed"),&ProjectSettings::_action_button_pressed);
  838. ObjectTypeDB::bind_method(_MD("_update_actions"),&ProjectSettings::_update_actions);
  839. ObjectTypeDB::bind_method(_MD("_wait_for_key"),&ProjectSettings::_wait_for_key);
  840. ObjectTypeDB::bind_method(_MD("_add_item"),&ProjectSettings::_add_item);
  841. ObjectTypeDB::bind_method(_MD("_device_input_add"),&ProjectSettings::_device_input_add);
  842. ObjectTypeDB::bind_method(_MD("_press_a_key_confirm"),&ProjectSettings::_press_a_key_confirm);
  843. ObjectTypeDB::bind_method(_MD("_settings_prop_edited"),&ProjectSettings::_settings_prop_edited);
  844. ObjectTypeDB::bind_method(_MD("_copy_to_platform"),&ProjectSettings::_copy_to_platform);
  845. ObjectTypeDB::bind_method(_MD("_update_translations"),&ProjectSettings::_update_translations);
  846. ObjectTypeDB::bind_method(_MD("_translation_delete"),&ProjectSettings::_translation_delete);
  847. ObjectTypeDB::bind_method(_MD("_settings_changed"),&ProjectSettings::_settings_changed);
  848. ObjectTypeDB::bind_method(_MD("_translation_add"),&ProjectSettings::_translation_add);
  849. ObjectTypeDB::bind_method(_MD("_translation_file_open"),&ProjectSettings::_translation_file_open);
  850. ObjectTypeDB::bind_method(_MD("_translation_res_add"),&ProjectSettings::_translation_res_add);
  851. ObjectTypeDB::bind_method(_MD("_translation_res_file_open"),&ProjectSettings::_translation_res_file_open);
  852. ObjectTypeDB::bind_method(_MD("_translation_res_option_add"),&ProjectSettings::_translation_res_option_add);
  853. ObjectTypeDB::bind_method(_MD("_translation_res_option_file_open"),&ProjectSettings::_translation_res_option_file_open);
  854. ObjectTypeDB::bind_method(_MD("_translation_res_select"),&ProjectSettings::_translation_res_select);
  855. ObjectTypeDB::bind_method(_MD("_translation_res_option_changed"),&ProjectSettings::_translation_res_option_changed);
  856. ObjectTypeDB::bind_method(_MD("_translation_res_delete"),&ProjectSettings::_translation_res_delete);
  857. ObjectTypeDB::bind_method(_MD("_translation_res_option_delete"),&ProjectSettings::_translation_res_option_delete);
  858. ObjectTypeDB::bind_method(_MD("_autoload_add"),&ProjectSettings::_autoload_add);
  859. ObjectTypeDB::bind_method(_MD("_autoload_file_open"),&ProjectSettings::_autoload_file_open);
  860. ObjectTypeDB::bind_method(_MD("_autoload_file_callback"),&ProjectSettings::_autoload_file_callback);
  861. ObjectTypeDB::bind_method(_MD("_update_autoload"),&ProjectSettings::_update_autoload);
  862. ObjectTypeDB::bind_method(_MD("_autoload_delete"),&ProjectSettings::_autoload_delete);
  863. }
  864. ProjectSettings::ProjectSettings(EditorData *p_data) {
  865. singleton=this;
  866. set_title("Project Settings (engine.cfg)");
  867. undo_redo=&p_data->get_undo_redo();
  868. data=p_data;
  869. TabContainer *tab_container = memnew( TabContainer );
  870. add_child(tab_container);
  871. set_child_rect(tab_container);
  872. //tab_container->set_anchor_and_margin(MARGIN_LEFT,ANCHOR_BEGIN, 15 );
  873. //tab_container->set_anchor_and_margin(MARGIN_RIGHT,ANCHOR_END, 15 );
  874. //tab_container->set_anchor_and_margin(MARGIN_TOP,ANCHOR_BEGIN, 15 );
  875. //tab_container->set_anchor_and_margin(MARGIN_BOTTOM,ANCHOR_END, 35 );
  876. Control *props_base = memnew( Control );
  877. tab_container->add_child(props_base);
  878. props_base->set_name("General");
  879. globals_editor = memnew( PropertyEditor );
  880. props_base->add_child(globals_editor);
  881. globals_editor->set_area_as_parent_rect();
  882. globals_editor->hide_top_label();
  883. globals_editor->set_anchor_and_margin(MARGIN_TOP,ANCHOR_BEGIN, 55 );
  884. globals_editor->set_anchor_and_margin(MARGIN_BOTTOM,ANCHOR_END, 35 );
  885. globals_editor->set_anchor_and_margin(MARGIN_LEFT,ANCHOR_BEGIN, 5 );
  886. globals_editor->set_anchor_and_margin(MARGIN_RIGHT,ANCHOR_END, 5 );
  887. globals_editor->set_capitalize_paths(false);
  888. globals_editor->get_tree()->connect("cell_selected",this,"_item_selected");
  889. globals_editor->connect("property_toggled",this,"_item_checked");
  890. globals_editor->connect("property_edited",this,"_settings_prop_edited");
  891. Label *l = memnew( Label );
  892. props_base->add_child(l);
  893. l->set_pos(Point2(6,5));
  894. l->set_text("Category:");
  895. l = memnew( Label );
  896. l->set_anchor(MARGIN_LEFT,ANCHOR_RATIO);
  897. props_base->add_child(l);
  898. l->set_begin(Point2(0.21,5));
  899. l->set_text("Property:");
  900. l = memnew( Label );
  901. l->set_anchor(MARGIN_LEFT,ANCHOR_RATIO);
  902. props_base->add_child(l);
  903. l->set_begin(Point2(0.51,5));
  904. l->set_text("Type:");
  905. category = memnew( LineEdit );
  906. props_base->add_child(category);
  907. category->set_anchor(MARGIN_RIGHT,ANCHOR_RATIO);
  908. category->set_begin( Point2(5,25) );
  909. category->set_end( Point2(0.20,26) );
  910. category->connect("text_entered",this,"_item_adds");
  911. property = memnew( LineEdit );
  912. props_base->add_child(property);
  913. property->set_anchor(MARGIN_LEFT,ANCHOR_RATIO);
  914. property->set_anchor(MARGIN_RIGHT,ANCHOR_RATIO);
  915. property->set_begin( Point2(0.21,25) );
  916. property->set_end( Point2(0.50,26) );
  917. property->connect("text_entered",this,"_item_adds");
  918. type = memnew( OptionButton );
  919. props_base->add_child(type);
  920. type->set_anchor(MARGIN_LEFT,ANCHOR_RATIO);
  921. type->set_anchor(MARGIN_RIGHT,ANCHOR_RATIO);
  922. type->set_begin( Point2(0.51,25) );
  923. type->set_end( Point2(0.70,26) );
  924. type->add_item("bool");
  925. type->add_item("int");
  926. type->add_item("float");
  927. type->add_item("string");
  928. Button *add = memnew( Button );
  929. props_base->add_child(add);
  930. add->set_anchor(MARGIN_LEFT,ANCHOR_RATIO);
  931. add->set_anchor(MARGIN_RIGHT,ANCHOR_RATIO);
  932. add->set_begin( Point2(0.71,25) );
  933. add->set_end( Point2(0.85,26) );
  934. add->set_text("Add");
  935. add->connect("pressed",this,"_item_add");
  936. Button *del = memnew( Button );
  937. props_base->add_child(del);
  938. del->set_anchor(MARGIN_LEFT,ANCHOR_RATIO);
  939. del->set_anchor(MARGIN_RIGHT,ANCHOR_END);
  940. del->set_begin( Point2(0.86,25) );
  941. del->set_end( Point2(5,26) );
  942. del->set_text("Del");
  943. del->connect("pressed",this,"_item_del");
  944. Button *save = memnew( Button );
  945. //props_base->add_child(save);
  946. save->set_anchor(MARGIN_LEFT,ANCHOR_END);
  947. save->set_anchor(MARGIN_RIGHT,ANCHOR_END);
  948. save->set_anchor(MARGIN_TOP,ANCHOR_END);
  949. save->set_anchor(MARGIN_BOTTOM,ANCHOR_END);
  950. save->set_begin( Point2(80,28) );
  951. save->set_end( Point2(10,20) );
  952. save->set_text("Save");
  953. save->connect("pressed",this,"_save");
  954. popup_platform = memnew( MenuButton );
  955. popup_platform->set_text("Copy To Platform..");
  956. popup_platform->set_disabled(true);
  957. props_base->add_child(popup_platform);
  958. popup_platform->set_anchor(MARGIN_LEFT,ANCHOR_BEGIN);
  959. popup_platform->set_anchor(MARGIN_RIGHT,ANCHOR_BEGIN);
  960. popup_platform->set_anchor(MARGIN_TOP,ANCHOR_END);
  961. popup_platform->set_anchor(MARGIN_BOTTOM,ANCHOR_END);
  962. popup_platform->set_begin( Point2(10,28) );
  963. popup_platform->set_end( Point2(150,20) );
  964. List<StringName> ep;
  965. EditorImportExport::get_singleton()->get_export_platforms(&ep);
  966. ep.sort_custom<StringName::AlphCompare>();
  967. for(List<StringName>::Element *E=ep.front();E;E=E->next()) {
  968. popup_platform->get_popup()->add_item( E->get() );
  969. }
  970. popup_platform->get_popup()->connect("item_pressed",this,"_copy_to_platform");
  971. get_ok()->set_text("Close");
  972. set_hide_on_ok(true);
  973. message = memnew( ConfirmationDialog );
  974. add_child(message);
  975. // message->get_cancel()->hide();
  976. message->set_hide_on_ok(true);
  977. Control *input_base = memnew( Control );
  978. input_base->set_name("Input Map");
  979. input_base->set_area_as_parent_rect();;
  980. tab_container->add_child(input_base);
  981. l = memnew( Label );
  982. input_base->add_child(l);
  983. l->set_pos(Point2(6,5));
  984. l->set_text("Action:");
  985. action_name = memnew( LineEdit );
  986. action_name->set_anchor(MARGIN_RIGHT,ANCHOR_RATIO);
  987. action_name->set_begin( Point2(5,25) );
  988. action_name->set_end( Point2(0.85,26) );
  989. input_base->add_child(action_name);
  990. action_name->connect("text_entered",this,"_action_adds");
  991. add = memnew( Button );
  992. input_base->add_child(add);
  993. add->set_anchor(MARGIN_LEFT,ANCHOR_RATIO);
  994. add->set_begin( Point2(0.86,25) );
  995. add->set_anchor(MARGIN_RIGHT,ANCHOR_END);
  996. add->set_end( Point2(5,26) );
  997. add->set_text("Add");
  998. add->connect("pressed",this,"_action_add");
  999. input_editor = memnew( Tree );
  1000. input_base->add_child(input_editor);
  1001. input_editor->set_area_as_parent_rect();
  1002. input_editor->set_anchor_and_margin(MARGIN_TOP,ANCHOR_BEGIN, 55 );
  1003. input_editor->set_anchor_and_margin(MARGIN_BOTTOM,ANCHOR_END, 35 );
  1004. input_editor->set_anchor_and_margin(MARGIN_LEFT,ANCHOR_BEGIN, 5 );
  1005. input_editor->set_anchor_and_margin(MARGIN_RIGHT,ANCHOR_END, 5 );
  1006. input_editor->connect("item_edited",this,"_action_persist_toggle");
  1007. input_editor->connect("button_pressed",this,"_action_button_pressed");
  1008. popup_add = memnew( PopupMenu );
  1009. add_child(popup_add);
  1010. popup_add->connect("item_pressed",this,"_add_item");
  1011. press_a_key = memnew( ConfirmationDialog );
  1012. press_a_key->set_focus_mode(FOCUS_ALL);
  1013. add_child(press_a_key);
  1014. l = memnew( Label );
  1015. l->set_text("Press a Key..");
  1016. l->set_area_as_parent_rect();
  1017. l->set_align(Label::ALIGN_CENTER);
  1018. l->set_margin(MARGIN_TOP,20);
  1019. l->set_anchor_and_margin(MARGIN_BOTTOM,ANCHOR_BEGIN,30);
  1020. press_a_key_label=l;
  1021. press_a_key->add_child(l);
  1022. press_a_key->connect("input_event",this,"_wait_for_key");
  1023. press_a_key->connect("confirmed",this,"_press_a_key_confirm");
  1024. device_input=memnew( ConfirmationDialog );
  1025. add_child(device_input);
  1026. device_input->get_ok()->set_text("Add");
  1027. device_input->connect("confirmed",this,"_device_input_add");
  1028. l = memnew( Label );
  1029. l->set_text("Device:");
  1030. l->set_pos(Point2(15,10));
  1031. device_input->add_child(l);
  1032. l = memnew( Label );
  1033. l->set_text("Index:");
  1034. l->set_pos(Point2(90,10));
  1035. device_input->add_child(l);
  1036. device_index_label=l;
  1037. device_id = memnew( SpinBox );
  1038. device_id->set_pos(Point2(20,30));
  1039. device_id->set_size(Size2(70,10));
  1040. device_id->set_val(0);
  1041. device_input->add_child(device_id);
  1042. device_index = memnew( OptionButton );
  1043. device_index->set_pos(Point2(95,30));
  1044. device_index->set_size(Size2(300,10));
  1045. device_index->set_anchor_and_margin(MARGIN_RIGHT,ANCHOR_END,10);
  1046. device_input->add_child(device_index);
  1047. save = memnew( Button );
  1048. input_base->add_child(save);
  1049. save->set_anchor(MARGIN_LEFT,ANCHOR_END);
  1050. save->set_anchor(MARGIN_RIGHT,ANCHOR_END);
  1051. save->set_anchor(MARGIN_TOP,ANCHOR_END);
  1052. save->set_anchor(MARGIN_BOTTOM,ANCHOR_END);
  1053. save->set_begin( Point2(80,28) );
  1054. save->set_end( Point2(10,20) );
  1055. save->set_text("Save");
  1056. save->connect("pressed",this,"_save");
  1057. setting=false;
  1058. //translations
  1059. TabContainer *translations = memnew( TabContainer );
  1060. translations->set_name("Localization");
  1061. tab_container->add_child(translations);
  1062. {
  1063. VBoxContainer *tvb = memnew( VBoxContainer );
  1064. translations->add_child(tvb);
  1065. tvb->set_name("Translations");
  1066. HBoxContainer *thb = memnew( HBoxContainer);
  1067. tvb->add_child(thb);
  1068. thb->add_child( memnew( Label("Translations:")));
  1069. thb->add_spacer();
  1070. Button *addtr = memnew( Button("Add..") );
  1071. addtr->connect("pressed",this,"_translation_file_open");
  1072. thb->add_child(addtr);
  1073. MarginContainer *tmc = memnew( MarginContainer );
  1074. tvb->add_child(tmc);
  1075. tmc->set_v_size_flags(SIZE_EXPAND_FILL);
  1076. translation_list = memnew( Tree );
  1077. translation_list->set_v_size_flags(SIZE_EXPAND_FILL);
  1078. tmc->add_child(translation_list);
  1079. translation_file_open=memnew( FileDialog );
  1080. add_child(translation_file_open);
  1081. translation_file_open->set_mode(FileDialog::MODE_OPEN_FILE);
  1082. translation_file_open->connect("file_selected",this,"_translation_add");
  1083. }
  1084. {
  1085. VBoxContainer *tvb = memnew( VBoxContainer );
  1086. translations->add_child(tvb);
  1087. tvb->set_name("Remaps");
  1088. HBoxContainer *thb = memnew( HBoxContainer);
  1089. tvb->add_child(thb);
  1090. thb->add_child( memnew( Label("Resources:")));
  1091. thb->add_spacer();
  1092. Button *addtr = memnew( Button("Add..") );
  1093. addtr->connect("pressed",this,"_translation_res_file_open");
  1094. thb->add_child(addtr);
  1095. MarginContainer *tmc = memnew( MarginContainer );
  1096. tvb->add_child(tmc);
  1097. tmc->set_v_size_flags(SIZE_EXPAND_FILL);
  1098. translation_remap = memnew( Tree );
  1099. translation_remap->set_v_size_flags(SIZE_EXPAND_FILL);
  1100. translation_remap->connect("cell_selected",this,"_translation_res_select");
  1101. tmc->add_child(translation_remap);
  1102. translation_remap->connect("button_pressed",this,"_translation_res_delete");
  1103. translation_res_file_open=memnew( FileDialog );
  1104. add_child(translation_res_file_open);
  1105. translation_res_file_open->set_mode(FileDialog::MODE_OPEN_FILE);
  1106. translation_res_file_open->connect("file_selected",this,"_translation_res_add");
  1107. thb = memnew( HBoxContainer);
  1108. tvb->add_child(thb);
  1109. thb->add_child( memnew( Label("Remaps by Locale:")));
  1110. thb->add_spacer();
  1111. addtr = memnew( Button("Add..") );
  1112. addtr->connect("pressed",this,"_translation_res_option_file_open");
  1113. translation_res_option_add_button=addtr;
  1114. thb->add_child(addtr);
  1115. tmc = memnew( MarginContainer );
  1116. tvb->add_child(tmc);
  1117. tmc->set_v_size_flags(SIZE_EXPAND_FILL);
  1118. translation_remap_options = memnew( Tree );
  1119. translation_remap_options->set_v_size_flags(SIZE_EXPAND_FILL);
  1120. tmc->add_child(translation_remap_options);
  1121. translation_remap_options->set_columns(2);
  1122. translation_remap_options->set_column_title(0,"Path");
  1123. translation_remap_options->set_column_title(1,"Locale");
  1124. translation_remap_options->set_column_titles_visible(true);
  1125. translation_remap_options->set_column_expand(0,true);
  1126. translation_remap_options->set_column_expand(1,false);
  1127. translation_remap_options->set_column_min_width(1,200);
  1128. translation_remap_options->connect("item_edited",this,"_translation_res_option_changed");
  1129. translation_remap_options->connect("button_pressed",this,"_translation_res_option_delete");
  1130. translation_res_option_file_open=memnew( FileDialog );
  1131. add_child(translation_res_option_file_open);
  1132. translation_res_option_file_open->set_mode(FileDialog::MODE_OPEN_FILE);
  1133. translation_res_option_file_open->connect("file_selected",this,"_translation_res_option_add");
  1134. }
  1135. {
  1136. VBoxContainer *avb = memnew( VBoxContainer );
  1137. tab_container->add_child(avb);
  1138. avb->set_name("AutoLoad");
  1139. HBoxContainer *ahb = memnew( HBoxContainer);
  1140. avb->add_child(ahb);
  1141. VBoxContainer *avb_name = memnew( VBoxContainer );
  1142. avb_name->set_h_size_flags(SIZE_EXPAND_FILL);
  1143. autoload_add_name = memnew(LineEdit);
  1144. avb_name->add_margin_child("Node Name:",autoload_add_name);
  1145. ahb->add_child(avb_name);
  1146. VBoxContainer *avb_path = memnew( VBoxContainer );
  1147. avb_path->set_h_size_flags(SIZE_EXPAND_FILL);
  1148. HBoxContainer *ahb_path = memnew( HBoxContainer );
  1149. autoload_add_path = memnew(LineEdit);
  1150. autoload_add_path->set_h_size_flags(SIZE_EXPAND_FILL);
  1151. ahb_path->add_child(autoload_add_path);
  1152. Button *browseaa = memnew( Button("..") );
  1153. ahb_path->add_child(browseaa);
  1154. browseaa->connect("pressed",this,"_autoload_file_open");
  1155. Button *addaa = memnew( Button("Add") );
  1156. ahb_path->add_child(addaa);
  1157. addaa->connect("pressed",this,"_autoload_add");
  1158. avb_path->add_margin_child("Path:",ahb_path);
  1159. ahb->add_child(avb_path);
  1160. autoload_list = memnew( Tree );
  1161. autoload_list->set_v_size_flags(SIZE_EXPAND_FILL);
  1162. avb->add_margin_child("List:",autoload_list,true);
  1163. autoload_file_open=memnew( FileDialog );
  1164. add_child(autoload_file_open);
  1165. autoload_file_open->set_mode(FileDialog::MODE_OPEN_FILE);
  1166. autoload_file_open->connect("file_selected",this,"_autoload_file_callback");
  1167. autoload_list->set_columns(2);
  1168. autoload_list->set_column_titles_visible(true);
  1169. autoload_list->set_column_title(0,"name");
  1170. autoload_list->set_column_title(1,"path");
  1171. autoload_list->connect("button_pressed",this,"_autoload_delete");
  1172. }
  1173. timer = memnew( Timer );
  1174. timer->set_wait_time(1.5);
  1175. timer->connect("timeout",Globals::get_singleton(),"save");
  1176. timer->set_one_shot(true);
  1177. add_child(timer);
  1178. updating_translations=false;
  1179. /*
  1180. Control * es = memnew( Control );
  1181. es->set_name("Export");
  1182. tab_container->add_child(es);
  1183. export_settings = memnew( ProjectExportSettings );
  1184. es->add_child(export_settings);
  1185. export_settings->set_area_as_parent_rect();
  1186. export_settings->set_anchor_and_margin(MARGIN_BOTTOM,ANCHOR_END, 35 );
  1187. */
  1188. }