box_projects.ts 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. let box_projects_htab: ui_handle_t = ui_handle_create();
  2. let box_projects_hsearch: ui_handle_t = ui_handle_create();
  3. let box_projects_icon_map: map_t<string, gpu_texture_t> = null;
  4. let _box_projects_path: string;
  5. let _box_projects_icon_path: string;
  6. let _box_projects_i: i32;
  7. function box_projects_show() {
  8. if (box_projects_icon_map != null) {
  9. let keys: string[] = map_keys(box_projects_icon_map);
  10. for (let i: i32 = 0; i < keys.length; ++i) {
  11. let handle: string = keys[i];
  12. data_delete_image(handle);
  13. }
  14. box_projects_icon_map = null;
  15. }
  16. let draggable: bool;
  17. ///if (arm_android || arm_ios)
  18. draggable = false;
  19. ///else
  20. draggable = true;
  21. ///end
  22. ui_box_show_custom(function (ui: ui_t) {
  23. ///if (arm_android || arm_ios)
  24. box_projects_align_to_fullscreen();
  25. ///end
  26. ///if (arm_android || arm_ios)
  27. box_projects_tab(ui);
  28. box_projects_get_started_tab(ui);
  29. ///else
  30. box_projects_recent_tab(ui);
  31. ///end
  32. }, 600, 400, null, draggable);
  33. }
  34. function box_projects_tab(ui: ui_t) {
  35. if (ui_tab(box_projects_htab, tr("Projects"), true)) {
  36. ui_begin_sticky();
  37. box_projects_draw_badge(ui);
  38. if (ui_button(tr("New"))) {
  39. project_new();
  40. viewport_scale_to_bounds();
  41. ui_box_hide();
  42. // Pick unique name
  43. let i: i32 = 0;
  44. let j: i32 = 0;
  45. let title: string = tr("untitled") + i;
  46. while (j < config_raw.recent_projects.length) {
  47. let base: string = config_raw.recent_projects[j];
  48. base = substring(base, string_last_index_of(base, path_sep) + 1, string_last_index_of(base, "."));
  49. j++;
  50. if (title == base) {
  51. i++;
  52. title = tr("untitled") + i;
  53. j = 0;
  54. }
  55. }
  56. sys_title_set(title);
  57. }
  58. ui_end_sticky();
  59. ui_separator(3, false);
  60. let slotw: i32 = math_floor(150 * ui_SCALE(ui));
  61. let num: i32 = math_floor(iron_window_width() / slotw);
  62. if (num == 0) {
  63. return;
  64. }
  65. let recent_projects: string[] = config_raw.recent_projects;
  66. let show_asset_names: bool = true;
  67. for (let row: i32 = 0; row < math_ceil(recent_projects.length / num); ++row) {
  68. let mult: i32 = show_asset_names ? 2 : 1;
  69. let ar: f32[] = [];
  70. for (let i: i32 = 0; i < num * mult; ++i) {
  71. array_push(ar, 1 / num);
  72. }
  73. ui_row(ar);
  74. ui._x += 2;
  75. let off: f32 = show_asset_names ? ui_ELEMENT_OFFSET(ui) * 16.0 : 6;
  76. if (row > 0) {
  77. ui._y += off;
  78. }
  79. for (let j: i32 = 0; j < num; ++j) {
  80. let imgw: i32 = math_floor(128 * ui_SCALE(ui));
  81. let i: i32 = j + row * num;
  82. if (i >= recent_projects.length) {
  83. _ui_end_element(imgw);
  84. if (show_asset_names) {
  85. _ui_end_element(0);
  86. }
  87. continue;
  88. }
  89. let path: string = recent_projects[i];
  90. ///if arm_ios
  91. let document_directory: string = iron_save_dialog("", "");
  92. document_directory = substring(document_directory, 0, document_directory.length - 8); // Strip /"untitled"
  93. path = document_directory + path;
  94. ///end
  95. let icon_path: string = substring(path, 0, path.length - 4) + "_icon.png";
  96. if (box_projects_icon_map == null) {
  97. box_projects_icon_map = map_create();
  98. }
  99. let icon: gpu_texture_t = map_get(box_projects_icon_map, icon_path);
  100. if (icon == null) {
  101. let image: gpu_texture_t = data_get_image(icon_path);
  102. icon = image;
  103. map_set(box_projects_icon_map, icon_path, icon);
  104. }
  105. let uix: i32 = ui._x;
  106. if (icon != null) {
  107. ui_fill(0, 0, 128, 128, ui.ops.theme.SEPARATOR_COL);
  108. let state: i32 = ui_image(icon, 0xffffffff, 128 * ui_SCALE(ui));
  109. if (state == ui_state_t.RELEASED) {
  110. let _uix: i32 = ui._x;
  111. ui._x = uix;
  112. ui_fill(0, 0, 128, 128, 0x66000000);
  113. ui._x = _uix;
  114. ///if (arm_android || arm_ios)
  115. console_toast(tr("Opening project"));
  116. ///end
  117. sys_notify_on_init(function (path: string) {
  118. ui_box_hide();
  119. import_arm_run_project(path);
  120. }, path);
  121. }
  122. let name: string = substring(path, string_last_index_of(path, path_sep) + 1, string_last_index_of(path, "."));
  123. if (ui.is_hovered && ui.input_released_r) {
  124. _box_projects_path = path;
  125. _box_projects_icon_path = icon_path;
  126. _box_projects_i = i;
  127. ui_menu_draw(function (ui: ui_t) {
  128. // if (ui_menu_button(tr("Duplicate"))) {}
  129. if (ui_menu_button(tr("Delete"))) {
  130. sys_notify_on_init(function () {
  131. file_delete(_box_projects_path);
  132. file_delete(_box_projects_icon_path);
  133. let data_path: string = substring(_box_projects_path, 0, _box_projects_path.length - 4);
  134. file_delete(data_path);
  135. let recent_projects: string[] = config_raw.recent_projects;
  136. array_splice(recent_projects, _box_projects_i, 1);
  137. });
  138. }
  139. });
  140. }
  141. if (show_asset_names) {
  142. ui._x = uix - (150 - 128) / 2;
  143. ui._y += slotw * 0.9;
  144. ui_text(name, ui_align_t.CENTER);
  145. if (ui.is_hovered) {
  146. ui_tooltip(name);
  147. }
  148. ui._y -= slotw * 0.9;
  149. if (i == recent_projects.length - 1) {
  150. ui._y += j == num - 1 ? imgw : imgw + ui_ELEMENT_H(ui) + ui_ELEMENT_OFFSET(ui);
  151. }
  152. }
  153. }
  154. else {
  155. _ui_end_element(0);
  156. if (show_asset_names) {
  157. _ui_end_element(0);
  158. }
  159. ui._x = uix;
  160. }
  161. }
  162. ui._y += 150;
  163. }
  164. }
  165. }
  166. function box_projects_recent_tab(ui: ui_t) {
  167. if (ui_tab(box_projects_htab, tr("Recent"), true)) {
  168. box_projects_draw_badge(ui);
  169. ui.enabled = config_raw.recent_projects.length > 0;
  170. box_projects_hsearch.text = ui_text_input(box_projects_hsearch, tr("Search"), ui_align_t.LEFT, true, true);
  171. ui.enabled = true;
  172. for (let i: i32 = 0; i < config_raw.recent_projects.length; ++i) {
  173. let path: string = config_raw.recent_projects[i];
  174. ///if arm_windows
  175. path = string_replace_all(path, "/", "\\");
  176. ///else
  177. path = string_replace_all(path, "\\", "/");
  178. ///end
  179. let file: string = substring(path, string_last_index_of(path, path_sep) + 1, path.length);
  180. if (string_index_of(to_lower_case(file), to_lower_case(box_projects_hsearch.text)) < 0) {
  181. continue; // Search filter
  182. }
  183. if (ui_button(file, ui_align_t.LEFT) && file_exists(path)) {
  184. let current: gpu_texture_t = _draw_current;
  185. let in_use: bool = gpu_in_use;
  186. if (in_use) draw_end();
  187. import_arm_run_project(path);
  188. if (in_use) draw_begin(current);
  189. ui_box_hide();
  190. }
  191. if (ui.is_hovered) {
  192. ui_tooltip(path);
  193. }
  194. }
  195. ui.enabled = config_raw.recent_projects.length > 0;
  196. if (ui_button(tr("Clear"), ui_align_t.LEFT)) {
  197. config_raw.recent_projects = [];
  198. config_save();
  199. }
  200. ui.enabled = true;
  201. _ui_end_element();
  202. if (ui_button(tr("New Project..."), ui_align_t.LEFT)) {
  203. project_new_box();
  204. }
  205. if (ui_button(tr("Open..."), ui_align_t.LEFT)) {
  206. project_open();
  207. }
  208. }
  209. }
  210. function box_projects_draw_badge(ui: ui_t) {
  211. let img: gpu_texture_t = data_get_image("badge.k");
  212. ui_image(img);
  213. _ui_end_element();
  214. }
  215. function box_projects_get_started_tab(ui: ui_t) {
  216. if (ui_tab(box_projects_htab, tr("Get Started"), true)) {
  217. if (ui_button(tr("Manual"))) {
  218. file_load_url(manifest_url + "/manual");
  219. }
  220. if (ui_button(tr("How To"))) {
  221. file_load_url(manifest_url + "/howto");
  222. }
  223. if (ui_button(tr("What's New"))) {
  224. file_load_url(manifest_url + "/notes");
  225. }
  226. }
  227. }
  228. function box_projects_align_to_fullscreen() {
  229. ui_box_modalw = math_floor(iron_window_width() / ui_SCALE(base_ui_box));
  230. ui_box_modalh = math_floor(iron_window_height() / ui_SCALE(base_ui_box));
  231. let appw: i32 = iron_window_width();
  232. let apph: i32 = iron_window_height();
  233. let mw: i32 = appw;
  234. let mh: i32 = apph;
  235. ui_box_hwnd.drag_x = math_floor(-appw / 2 + mw / 2);
  236. ui_box_hwnd.drag_y = math_floor(-apph / 2 + mh / 2);
  237. }