box_projects.ts 7.3 KB

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