box_preferences.ts 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968
  1. let box_preferences_htab: zui_handle_t = zui_handle_create();
  2. let box_preferences_files_plugin: string[] = null;
  3. let box_preferences_files_keymap: string[] = null;
  4. let box_preferences_theme_handle: zui_handle_t;
  5. let box_preferences_preset_handle: zui_handle_t;
  6. let box_preferences_locales: string[] = null;
  7. let box_preferences_themes: string[] = null;
  8. let box_preferences_world_color: i32 = 0xff080808;
  9. function box_preferences_show() {
  10. ui_box_show_custom(function (ui: zui_t) {
  11. if (zui_tab(box_preferences_htab, tr("Interface"), true)) {
  12. if (box_preferences_locales == null) {
  13. box_preferences_locales = translator_get_supported_locales();
  14. }
  15. let locale_handle: zui_handle_t = zui_handle(__ID__);
  16. if (locale_handle.init) {
  17. locale_handle.position = array_index_of(box_preferences_locales, config_raw.locale);
  18. }
  19. zui_combo(locale_handle, box_preferences_locales, tr("Language"), true);
  20. if (locale_handle.changed) {
  21. let locale_code: string = box_preferences_locales[locale_handle.position];
  22. config_raw.locale = locale_code;
  23. translator_load_translations(locale_code);
  24. ui_base_tag_ui_redraw();
  25. }
  26. let hscale: zui_handle_t = zui_handle(__ID__);
  27. if (hscale.init) {
  28. hscale.value = config_raw.window_scale;
  29. }
  30. zui_slider(hscale, tr("UI Scale"), 1.0, 4.0, true, 10);
  31. if (context_raw.hscale_was_changed && !ui.input_down) {
  32. context_raw.hscale_was_changed = false;
  33. if (hscale.value == null) {
  34. hscale.value = 1.0;
  35. }
  36. config_raw.window_scale = hscale.value;
  37. box_preferences_set_scale();
  38. }
  39. if (hscale.changed) {
  40. context_raw.hscale_was_changed = true;
  41. }
  42. let hspeed: zui_handle_t = zui_handle(__ID__);
  43. if (hspeed.init) {
  44. hspeed.value = config_raw.camera_zoom_speed;
  45. }
  46. config_raw.camera_zoom_speed = zui_slider(hspeed, tr("Camera Zoom Speed"), 0.1, 4.0, true);
  47. hspeed = zui_handle(__ID__);
  48. if (hspeed.init) {
  49. hspeed.value = config_raw.camera_rotation_speed;
  50. }
  51. config_raw.camera_rotation_speed = zui_slider(hspeed, tr("Camera Rotation Speed"), 0.1, 4.0, true);
  52. hspeed = zui_handle(__ID__);
  53. if (hspeed.init) {
  54. hspeed.value = config_raw.camera_pan_speed;
  55. }
  56. config_raw.camera_pan_speed = zui_slider(hspeed, tr("Camera Pan Speed"), 0.1, 4.0, true);
  57. let zoom_direction_handle: zui_handle_t = zui_handle(__ID__);
  58. if (zoom_direction_handle.init) {
  59. zoom_direction_handle.position = config_raw.zoom_direction;
  60. }
  61. let zoom_direction_combo: string[] = [tr("Vertical"), tr("Vertical Inverted"), tr("Horizontal"), tr("Horizontal Inverted"), tr("Vertical and Horizontal"), tr("Vertical and Horizontal Inverted")];
  62. zui_combo(zoom_direction_handle, zoom_direction_combo, tr("Direction to Zoom"), true);
  63. if (zoom_direction_handle.changed) {
  64. config_raw.zoom_direction = zoom_direction_handle.position;
  65. }
  66. let h_wrap_mouse: zui_handle_t = zui_handle(__ID__);
  67. if (h_wrap_mouse.init) {
  68. h_wrap_mouse.selected = config_raw.wrap_mouse;
  69. }
  70. config_raw.wrap_mouse = zui_check(h_wrap_mouse, tr("Wrap Mouse"));
  71. if (ui.is_hovered) {
  72. zui_tooltip(tr("Wrap mouse around view boundaries during camera control"));
  73. }
  74. let h_node_preview: zui_handle_t = zui_handle(__ID__);
  75. if (h_node_preview.init) {
  76. h_node_preview.selected = config_raw.node_preview;
  77. }
  78. config_raw.node_preview = zui_check(h_node_preview, tr("Show Node Preview"));
  79. ui.changed = false;
  80. let h_show_asset_names: zui_handle_t = zui_handle(__ID__);
  81. if (h_show_asset_names.init) {
  82. h_show_asset_names.selected = config_raw.show_asset_names;
  83. }
  84. config_raw.show_asset_names = zui_check(h_show_asset_names, tr("Show Asset Names"));
  85. if (ui.changed) {
  86. ui_base_tag_ui_redraw();
  87. }
  88. ///if !(krom_android || krom_ios)
  89. ui.changed = false;
  90. let h_touch_ui: zui_handle_t = zui_handle(__ID__);
  91. if (h_touch_ui.init) {
  92. h_touch_ui.selected = config_raw.touch_ui;
  93. }
  94. config_raw.touch_ui = zui_check(h_touch_ui, tr("Touch UI"));
  95. if (ui.changed) {
  96. zui_set_touch_scroll(config_raw.touch_ui);
  97. zui_set_touch_hold(config_raw.touch_ui);
  98. zui_set_touch_tooltip(config_raw.touch_ui);
  99. config_load_theme(config_raw.theme);
  100. box_preferences_set_scale();
  101. ui_base_tag_ui_redraw();
  102. }
  103. ///end
  104. let h_splash_screen: zui_handle_t = zui_handle(__ID__);
  105. if (h_splash_screen.init) {
  106. h_splash_screen.selected = config_raw.splash_screen;
  107. }
  108. config_raw.splash_screen = zui_check(h_splash_screen, tr("Splash Screen"));
  109. // zui_text("Node Editor");
  110. // let grid_snap: bool = Zui.check(Zui.handle("boxpreferences_11", { selected: false }), "Grid Snap");
  111. zui_end_element();
  112. let row: f32[] = [0.5, 0.5];
  113. zui_row(row);
  114. if (zui_button(tr("Restore")) && !ui_menu_show) {
  115. ui_menu_draw(function (ui: zui_t) {
  116. if (ui_menu_button(ui, tr("Confirm"))) {
  117. app_notify_on_init(function () {
  118. ui.ops.theme.ELEMENT_H = base_default_element_h;
  119. config_restore();
  120. box_preferences_set_scale();
  121. if (box_preferences_files_plugin != null) {
  122. for (let i: i32 = 0; i < box_preferences_files_plugin.length; ++i) {
  123. let f: string = box_preferences_files_plugin[i];
  124. plugin_stop(f);
  125. }
  126. }
  127. box_preferences_files_plugin = null;
  128. box_preferences_files_keymap = null;
  129. make_material_parse_mesh_material();
  130. make_material_parse_paint_material();
  131. });
  132. }
  133. if (ui_menu_button(ui, tr("Import..."))) {
  134. ui_files_show("json", false, false, function (path: string) {
  135. let b: buffer_t = data_get_blob(path);
  136. let raw: config_t = json_parse(sys_buffer_to_string(b));
  137. app_notify_on_init(function (raw: config_t) {
  138. ui.ops.theme.ELEMENT_H = base_default_element_h;
  139. config_import_from(raw);
  140. box_preferences_set_scale();
  141. make_material_parse_mesh_material();
  142. make_material_parse_paint_material();
  143. }, raw);
  144. });
  145. }
  146. }, 2);
  147. }
  148. if (zui_button(tr("Reset Layout")) && !ui_menu_show) {
  149. ui_menu_draw(function (ui: zui_t) {
  150. if (ui_menu_button(ui, tr("Confirm"))) {
  151. base_init_layout();
  152. config_save();
  153. }
  154. }, 1);
  155. }
  156. }
  157. if (zui_tab(box_preferences_htab, tr("Theme"), true)) {
  158. if (box_preferences_themes == null) {
  159. box_preferences_fetch_themes();
  160. }
  161. box_preferences_theme_handle = zui_handle(__ID__);
  162. if (box_preferences_theme_handle.init) {
  163. box_preferences_theme_handle.position = box_preferences_get_theme_index();
  164. }
  165. zui_begin_sticky();
  166. let row: f32[] = [1 / 4, 1 / 4, 1 / 4, 1 / 4];
  167. zui_row(row);
  168. zui_combo(box_preferences_theme_handle, box_preferences_themes, tr("Theme"));
  169. if (box_preferences_theme_handle.changed) {
  170. config_raw.theme = box_preferences_themes[box_preferences_theme_handle.position] + ".json";
  171. config_load_theme(config_raw.theme);
  172. }
  173. if (zui_button(tr("New"))) {
  174. ui_box_show_custom(function (ui: zui_t) {
  175. if (zui_tab(zui_handle(__ID__), tr("New Theme"))) {
  176. let row: f32[] = [0.5, 0.5];
  177. zui_row(row);
  178. let h: zui_handle_t = zui_handle(__ID__);
  179. if (h.init) {
  180. h.text = "new_theme";
  181. }
  182. let theme_name: string = zui_text_input(h, tr("Name"));
  183. if (zui_button(tr("OK")) || ui.is_return_down) {
  184. let template: string = json_stringify(base_theme);
  185. if (!ends_with(theme_name, ".json")) {
  186. theme_name += ".json";
  187. }
  188. let path: string = path_data() + path_sep + "themes" + path_sep + theme_name;
  189. krom_file_save_bytes(path, sys_string_to_buffer(template));
  190. box_preferences_fetch_themes(); // Refresh file list
  191. config_raw.theme = theme_name;
  192. box_preferences_theme_handle.position = box_preferences_get_theme_index();
  193. ui_box_hide();
  194. box_preferences_htab.position = 1; // Themes
  195. box_preferences_show();
  196. }
  197. }
  198. });
  199. }
  200. if (zui_button(tr("Import"))) {
  201. ui_files_show("json", false, false, function (path: string) {
  202. import_theme_run(path);
  203. });
  204. }
  205. if (zui_button(tr("Export"))) {
  206. ui_files_show("json", true, false, function (path: string) {
  207. path += path_sep + ui_files_filename;
  208. if (!ends_with(path, ".json")) {
  209. path += ".json";
  210. }
  211. krom_file_save_bytes(path, sys_string_to_buffer(json_stringify(base_theme)));
  212. });
  213. }
  214. zui_end_sticky();
  215. let i: i32 = 0;
  216. let theme: any = base_theme;
  217. let hlist: zui_handle_t = zui_handle(__ID__);
  218. // Viewport color
  219. let h: zui_handle_t = zui_nest(hlist, i++);
  220. if (h.init) {
  221. h.color = box_preferences_world_color;
  222. }
  223. row = [1 / 8, 7 / 8];
  224. zui_row(row);
  225. zui_text("", 0, h.color);
  226. if (ui.is_hovered && ui.input_released) {
  227. ui_menu_draw(function (ui: zui_t) {
  228. ui.changed = false;
  229. zui_color_wheel(h, false, null, 11 * ui.ops.theme.ELEMENT_H * zui_SCALE(ui), true);
  230. if (ui.changed) {
  231. ui_menu_keep_open = true;
  232. }
  233. }, 11);
  234. }
  235. let val: i32 = h.color;
  236. if (val < 0) {
  237. val += 4294967296;
  238. }
  239. h.text = i32_to_string_hex(val);
  240. zui_text_input(h, "VIEWPORT_COL");
  241. h.color = parse_int_hex(h.text);
  242. if (box_preferences_world_color != h.color) {
  243. box_preferences_world_color = h.color;
  244. let b: u8_array_t = u8_array_create(4);
  245. b[0] = color_get_rb(box_preferences_world_color);
  246. b[1] = color_get_gb(box_preferences_world_color);
  247. b[2] = color_get_bb(box_preferences_world_color);
  248. b[3] = 255;
  249. context_raw.empty_envmap = image_from_bytes(b.buffer, 1, 1);
  250. context_raw.ddirty = 2;
  251. if (!context_raw.show_envmap) {
  252. scene_world._.envmap = context_raw.empty_envmap;
  253. }
  254. }
  255. // Theme fields
  256. for (let i: i32 = 0; i < zui_theme_keys.length; ++i) {
  257. let key: string = zui_theme_keys[i];
  258. let h: zui_handle_t = zui_nest(hlist, i);
  259. let val: any = theme[key];
  260. let is_hex: bool = ends_with(key, "_COL");
  261. if (is_hex && val < 0) {
  262. val += 4294967296;
  263. }
  264. if (is_hex) {
  265. let row: f32[] = [1 / 8, 7 / 8];
  266. zui_row(row);
  267. zui_text("", 0, val);
  268. if (ui.is_hovered && ui.input_released) {
  269. h.color = theme[key];
  270. ui_menu_draw(function (ui: zui_t) {
  271. ui.changed = false;
  272. let color: i32 = zui_color_wheel(h, false, null, 11 * ui.ops.theme.ELEMENT_H * zui_SCALE(ui), true);
  273. let theme: any = base_theme;
  274. theme[key] = color;
  275. if (ui.changed) {
  276. ui_menu_keep_open = true;
  277. }
  278. }, 11);
  279. }
  280. }
  281. ui.changed = false;
  282. if (key == "FILL_WINDOW_BG" ||
  283. key == "FILL_BUTTON_BG" ||
  284. key == "FILL_ACCENT_BG" ||
  285. key == "FULL_TABS" ||
  286. key == "ROUND_CORNERS") {
  287. h.selected = val;
  288. let b: bool = zui_check(h, key);
  289. theme[key] = b;
  290. }
  291. else if (key == "LINK_STYLE") {
  292. let styles: string[] = [tr("Straight"), tr("Curved")];
  293. h.position = val;
  294. let i: i32 = zui_combo(h, styles, key, true);
  295. theme[key] = i;
  296. }
  297. else {
  298. h.text = is_hex ? i32_to_string_hex(val) : i32_to_string(val);
  299. zui_text_input(h, key);
  300. if (is_hex) {
  301. theme[key] = parse_int_hex(h.text);
  302. }
  303. else {
  304. theme[key] = parse_int(h.text);
  305. }
  306. }
  307. if (ui.changed) {
  308. for (let i: i32 = 0; i < base_get_uis().length; ++i) {
  309. let ui: zui_t = base_get_uis()[i];
  310. ui.elements_baked = false;
  311. }
  312. }
  313. }
  314. }
  315. if (zui_tab(box_preferences_htab, tr("Usage"), true)) {
  316. context_raw.undo_handle = zui_handle(__ID__);
  317. if (context_raw.undo_handle.init) {
  318. context_raw.undo_handle.value = config_raw.undo_steps;
  319. }
  320. config_raw.undo_steps = math_floor(zui_slider(context_raw.undo_handle, tr("Undo Steps"), 1, 64, false, 1));
  321. if (config_raw.undo_steps < 1) {
  322. config_raw.undo_steps = math_floor(context_raw.undo_handle.value = 1);
  323. }
  324. if (context_raw.undo_handle.changed) {
  325. let current: image_t = _g2_current;
  326. g2_end();
  327. ///if (is_paint || is_sculpt)
  328. while (history_undo_layers.length < config_raw.undo_steps) {
  329. let l: slot_layer_t = slot_layer_create("_undo" + history_undo_layers.length);
  330. array_push(history_undo_layers, l);
  331. }
  332. while (history_undo_layers.length > config_raw.undo_steps) {
  333. let l: slot_layer_t = history_undo_layers.pop();
  334. slot_layer_unload(l);
  335. }
  336. ///end
  337. history_reset();
  338. g2_begin(current);
  339. }
  340. ///if is_paint
  341. let h_dilate_radius: zui_handle_t = zui_handle(__ID__);
  342. if (h_dilate_radius.init) {
  343. h_dilate_radius.value = config_raw.dilate_radius;
  344. }
  345. config_raw.dilate_radius = math_floor(zui_slider(h_dilate_radius, tr("Dilate Radius"), 0.0, 16.0, true, 1));
  346. if (ui.is_hovered) {
  347. zui_tooltip(tr("Dilate painted textures to prevent seams"));
  348. }
  349. let dilate_handle: zui_handle_t = zui_handle(__ID__);
  350. if (dilate_handle.init) {
  351. dilate_handle.position = config_raw.dilate;
  352. }
  353. let dilate_combo: string[] = [tr("Instant"), tr("Delayed")];
  354. zui_combo(dilate_handle, dilate_combo, tr("Dilate"), true);
  355. if (dilate_handle.changed) {
  356. config_raw.dilate = dilate_handle.position;
  357. }
  358. ///end
  359. ///if is_lab
  360. let workspace_handle: zui_handle_t = zui_handle(__ID__);
  361. if (workspace_handle.init) {
  362. workspace_handle.position = config_raw.workspace;
  363. }
  364. let workspace_combo: string[] = [tr("3D View"), tr("2D View")];
  365. zui_combo(workspace_handle, workspace_combo, tr("Default Workspace"), true);
  366. if (workspace_handle.changed) {
  367. config_raw.workspace = workspace_handle.position;
  368. }
  369. ///end
  370. let camera_controls_handle: zui_handle_t = zui_handle(__ID__);
  371. if (camera_controls_handle.init) {
  372. camera_controls_handle.position = config_raw.camera_controls;
  373. }
  374. let camera_controls_combo: string[] = [tr("Orbit"), tr("Rotate"), tr("Fly")];
  375. zui_combo(camera_controls_handle, camera_controls_combo, tr("Default Camera Controls"), true);
  376. if (camera_controls_handle.changed) {
  377. config_raw.camera_controls = camera_controls_handle.position;
  378. }
  379. let layer_res_handle: zui_handle_t = zui_handle(__ID__);
  380. if (layer_res_handle.init) {
  381. layer_res_handle.position = config_raw.layer_res;
  382. }
  383. ///if is_paint
  384. ///if (krom_android || krom_ios)
  385. let layer_res_combo: string[] = ["128", "256", "512", "1K", "2K", "4K"];
  386. zui_combo(layer_res_handle, layer_res_combo, tr("Default Layer Resolution"), true);
  387. ///else
  388. let layer_res_combo: string[] = ["128", "256", "512", "1K", "2K", "4K", "8K"];
  389. zui_combo(layer_res_handle, layer_res_combo, tr("Default Layer Resolution"), true);
  390. ///end
  391. ///end
  392. ///if is_lab
  393. ///if (krom_android || krom_ios)
  394. let layer_res_combo: string[] = ["2K", "4K"];
  395. zui_combo(layer_res_handle, layer_res_combo, tr("Default Layer Resolution"), true);
  396. ///else
  397. let layer_res_combo: string[] = ["2K", "4K", "8K", "16K"];
  398. zui_combo(layer_res_handle, layer_res_combo, tr("Default Layer Resolution"), true);
  399. ///end
  400. ///end
  401. if (layer_res_handle.changed) {
  402. config_raw.layer_res = layer_res_handle.position;
  403. }
  404. let server_handle: zui_handle_t = zui_handle(__ID__);
  405. if (server_handle.init) {
  406. server_handle.text = config_raw.server;
  407. }
  408. config_raw.server = zui_text_input(server_handle, tr("Cloud Server"));
  409. ///if (is_paint || is_sculpt)
  410. let material_live_handle: zui_handle_t = zui_handle(__ID__);
  411. if (material_live_handle.init) {
  412. material_live_handle.selected = config_raw.material_live;
  413. }
  414. config_raw.material_live = zui_check(material_live_handle, tr("Live Material Preview"));
  415. if (ui.is_hovered) {
  416. zui_tooltip(tr("Instantly update material preview on node change"));
  417. }
  418. let brush_live_handle: zui_handle_t = zui_handle(__ID__);
  419. if (brush_live_handle.init) {
  420. brush_live_handle.selected = config_raw.brush_live;
  421. }
  422. config_raw.brush_live = zui_check(brush_live_handle, tr("Live Brush Preview"));
  423. if (ui.is_hovered) {
  424. zui_tooltip(tr("Draw live brush preview in viewport"));
  425. }
  426. if (brush_live_handle.changed) {
  427. context_raw.ddirty = 2;
  428. }
  429. let brush_3d_handle: zui_handle_t = zui_handle(__ID__);
  430. if (brush_3d_handle.init) {
  431. brush_3d_handle.selected = config_raw.brush_3d;
  432. }
  433. config_raw.brush_3d = zui_check(brush_3d_handle, tr("3D Cursor"));
  434. if (brush_3d_handle.changed) {
  435. make_material_parse_paint_material();
  436. }
  437. ui.enabled = config_raw.brush_3d;
  438. let brush_depth_reject_handle: zui_handle_t = zui_handle(__ID__);
  439. if (brush_depth_reject_handle.init) {
  440. brush_depth_reject_handle.selected = config_raw.brush_depth_reject;
  441. }
  442. config_raw.brush_depth_reject = zui_check(brush_depth_reject_handle, tr("Depth Reject"));
  443. if (brush_depth_reject_handle.changed) {
  444. make_material_parse_paint_material();
  445. }
  446. let row: f32[] = [0.5, 0.5];
  447. zui_row(row);
  448. let brush_angle_reject_handle: zui_handle_t = zui_handle(__ID__);
  449. if (brush_angle_reject_handle.init) {
  450. brush_angle_reject_handle.selected = config_raw.brush_angle_reject;
  451. }
  452. config_raw.brush_angle_reject = zui_check(brush_angle_reject_handle, tr("Angle Reject"));
  453. if (brush_angle_reject_handle.changed) {
  454. make_material_parse_paint_material();
  455. }
  456. if (!config_raw.brush_angle_reject) ui.enabled = false;
  457. let angle_dot_handle: zui_handle_t = zui_handle(__ID__);
  458. if (angle_dot_handle.init) {
  459. angle_dot_handle.value = context_raw.brush_angle_reject_dot;
  460. }
  461. context_raw.brush_angle_reject_dot = zui_slider(angle_dot_handle, tr("Angle"), 0.0, 1.0, true);
  462. if (angle_dot_handle.changed) {
  463. make_material_parse_paint_material();
  464. }
  465. ui.enabled = true;
  466. ///end
  467. ///if is_lab
  468. let h_gpu_inference: zui_handle_t = zui_handle(__ID__);
  469. if (h_gpu_inference.init) {
  470. h_gpu_inference.selected = config_raw.gpu_inference;
  471. }
  472. config_raw.gpu_inference = zui_check(h_gpu_inference, tr("Use GPU"));
  473. if (ui.is_hovered) {
  474. zui_tooltip(tr("Use GPU to accelerate node graph processing"));
  475. }
  476. ///end
  477. }
  478. let pen_name: string;
  479. ///if krom_ios
  480. pen_name = tr("Pencil");
  481. ///else
  482. pen_name = tr("Pen");
  483. ///end
  484. if (zui_tab(box_preferences_htab, pen_name, true)) {
  485. zui_text(tr("Pressure controls"));
  486. let h_pressure_radius: zui_handle_t = zui_handle(__ID__);
  487. if (h_pressure_radius.init) {
  488. h_pressure_radius.selected = config_raw.pressure_radius;
  489. }
  490. config_raw.pressure_radius = zui_check(h_pressure_radius, tr("Brush Radius"));
  491. let h_pressure_sensitivity: zui_handle_t = zui_handle(__ID__);
  492. if (h_pressure_sensitivity.init) {
  493. h_pressure_sensitivity.value = config_raw.pressure_sensitivity;
  494. }
  495. config_raw.pressure_sensitivity = zui_slider(h_pressure_sensitivity, tr("Sensitivity"), 0.0, 10.0, true);
  496. ///if (is_paint || is_sculpt)
  497. let h_pressure_hardness: zui_handle_t = zui_handle(__ID__);
  498. if (h_pressure_hardness.init) {
  499. h_pressure_hardness.selected = config_raw.pressure_hardness;
  500. }
  501. config_raw.pressure_hardness = zui_check(h_pressure_hardness, tr("Brush Hardness"));
  502. let h_pressure_opacity: zui_handle_t = zui_handle(__ID__);
  503. if (h_pressure_opacity.init) {
  504. h_pressure_opacity.selected = config_raw.pressure_opacity;
  505. }
  506. config_raw.pressure_opacity = zui_check(h_pressure_opacity, tr("Brush Opacity"));
  507. let h_pressure_angle: zui_handle_t = zui_handle(__ID__);
  508. if (h_pressure_angle.init) {
  509. h_pressure_angle.selected = config_raw.pressure_angle;
  510. }
  511. config_raw.pressure_angle = zui_check(h_pressure_angle, tr("Brush Angle"));
  512. ///end
  513. zui_end_element();
  514. let row: f32[] = [0.5];
  515. zui_row(row);
  516. if (zui_button(tr("Help"))) {
  517. ///if (is_paint || is_sculpt)
  518. file_load_url("https://github.com/armory3d/armorpaint_docs///pen");
  519. ///end
  520. ///if is_lab
  521. file_load_url("https://github.com/armory3d/armorlab_docs///pen");
  522. ///end
  523. }
  524. }
  525. context_raw.hssao = zui_handle(__ID__);
  526. if (context_raw.hssao.init) {
  527. context_raw.hssao.selected = config_raw.rp_ssao;
  528. }
  529. context_raw.hssr = zui_handle(__ID__);
  530. if (context_raw.hssr.init) {
  531. context_raw.hssr.selected = config_raw.rp_ssr;
  532. }
  533. context_raw.hbloom = zui_handle(__ID__);
  534. if (context_raw.hbloom.init) {
  535. context_raw.hbloom.selected = config_raw.rp_bloom;
  536. }
  537. context_raw.hsupersample = zui_handle(__ID__);
  538. if (context_raw.hsupersample.init) {
  539. context_raw.hsupersample.position = config_get_super_sample_quality(config_raw.rp_supersample);
  540. }
  541. context_raw.hvxao = zui_handle(__ID__);
  542. if (context_raw.hvxao.init) {
  543. context_raw.hvxao.selected = config_raw.rp_gi;
  544. }
  545. if (zui_tab(box_preferences_htab, tr("Viewport"), true)) {
  546. ///if (krom_direct3d12 || krom_vulkan || krom_metal)
  547. let hpathtrace_mode: zui_handle_t = zui_handle(__ID__);
  548. if (hpathtrace_mode.init) {
  549. hpathtrace_mode.position = context_raw.pathtrace_mode;
  550. }
  551. let pathtrace_mode_combo: string[] = [tr("Core"), tr("Full")];
  552. context_raw.pathtrace_mode = zui_combo(hpathtrace_mode, pathtrace_mode_combo, tr("Path Tracer"), true);
  553. if (hpathtrace_mode.changed) {
  554. render_path_raytrace_ready = false;
  555. }
  556. ///end
  557. let hrender_mode: zui_handle_t = zui_handle(__ID__);
  558. if (hrender_mode.init) {
  559. hrender_mode.position = context_raw.render_mode;
  560. }
  561. let render_mode_combo: string[] = [tr("Full"), tr("Mobile")];
  562. context_raw.render_mode = zui_combo(hrender_mode, render_mode_combo, tr("Renderer"), true);
  563. if (hrender_mode.changed) {
  564. context_set_render_path();
  565. }
  566. let supersample_combo: string[] = ["0.25x", "0.5x", "1.0x", "1.5x", "2.0x", "4.0x"];
  567. zui_combo(context_raw.hsupersample, supersample_combo, tr("Super Sample"), true);
  568. if (context_raw.hsupersample.changed) {
  569. config_apply();
  570. }
  571. if (context_raw.render_mode == render_mode_t.DEFERRED) {
  572. ///if arm_voxels
  573. zui_check(context_raw.hvxao, tr("Voxel AO"));
  574. if (ui.is_hovered) {
  575. zui_tooltip(tr("Cone-traced AO and shadows"));
  576. }
  577. if (context_raw.hvxao.changed) {
  578. config_apply();
  579. }
  580. ui.enabled = context_raw.hvxao.selected;
  581. let h: zui_handle_t = zui_handle(__ID__);
  582. if (h.init) {
  583. h.value = context_raw.vxao_offset;
  584. }
  585. context_raw.vxao_offset = zui_slider(h, tr("Cone Offset"), 1.0, 4.0, true);
  586. if (h.changed) {
  587. context_raw.ddirty = 2;
  588. }
  589. h = zui_handle(__ID__);
  590. if (h.init) {
  591. h.value = context_raw.vxao_aperture;
  592. }
  593. context_raw.vxao_aperture = zui_slider(h, tr("Aperture"), 1.0, 4.0, true);
  594. if (h.changed) {
  595. context_raw.ddirty = 2;
  596. }
  597. ui.enabled = true;
  598. ///end
  599. zui_check(context_raw.hssao, tr("SSAO"));
  600. if (context_raw.hssao.changed) {
  601. config_apply();
  602. }
  603. zui_check(context_raw.hssr, tr("SSR"));
  604. if (context_raw.hssr.changed) {
  605. config_apply();
  606. }
  607. zui_check(context_raw.hbloom, tr("Bloom"));
  608. if (context_raw.hbloom.changed) {
  609. config_apply();
  610. }
  611. }
  612. let h: zui_handle_t = zui_handle(__ID__);
  613. if (h.init) {
  614. h.value = config_raw.rp_vignette;
  615. }
  616. config_raw.rp_vignette = zui_slider(h, tr("Vignette"), 0.0, 1.0, true);
  617. if (h.changed) {
  618. context_raw.ddirty = 2;
  619. }
  620. h = zui_handle(__ID__);
  621. if (h.init) {
  622. h.value = config_raw.rp_grain;
  623. }
  624. config_raw.rp_grain = zui_slider(h, tr("Noise Grain"), 0.0, 1.0, true);
  625. if (h.changed) {
  626. context_raw.ddirty = 2;
  627. }
  628. // let h: zui_handle_t = Zui.handle("boxpreferences_46", { value: raw.autoExposureStrength });
  629. // raw.autoExposureStrength = Zui.slider(h, "Auto Exposure", 0.0, 2.0, true);
  630. // if (h.changed) raw.ddirty = 2;
  631. let cam: camera_object_t = scene_camera;
  632. let cam_raw: camera_data_t = cam.data;
  633. let near_handle: zui_handle_t = zui_handle(__ID__);
  634. let far_handle: zui_handle_t = zui_handle(__ID__);
  635. near_handle.value = math_floor(cam_raw.near_plane * 1000) / 1000;
  636. far_handle.value = math_floor(cam_raw.far_plane * 100) / 100;
  637. cam_raw.near_plane = zui_slider(near_handle, tr("Clip Start"), 0.001, 1.0, true);
  638. cam_raw.far_plane = zui_slider(far_handle, tr("Clip End"), 50.0, 100.0, true);
  639. if (near_handle.changed || far_handle.changed) {
  640. camera_object_build_proj(cam);
  641. }
  642. let disp_handle: zui_handle_t = zui_handle(__ID__);
  643. if (disp_handle.init) {
  644. disp_handle.value = config_raw.displace_strength;
  645. }
  646. config_raw.displace_strength = zui_slider(disp_handle, tr("Displacement Strength"), 0.0, 10.0, true);
  647. if (disp_handle.changed) {
  648. context_raw.ddirty = 2;
  649. make_material_parse_mesh_material();
  650. }
  651. }
  652. if (zui_tab(box_preferences_htab, tr("Keymap"), true)) {
  653. if (box_preferences_files_keymap == null) {
  654. box_preferences_fetch_keymaps();
  655. }
  656. zui_begin_sticky();
  657. let row: f32[] = [1 / 4, 1 / 4, 1 / 4, 1 / 4];
  658. zui_row(row);
  659. box_preferences_preset_handle = zui_handle(__ID__);
  660. if (box_preferences_preset_handle.init) {
  661. box_preferences_preset_handle.position = box_preferences_get_preset_index();
  662. }
  663. zui_combo(box_preferences_preset_handle, box_preferences_files_keymap, tr("Preset"));
  664. if (box_preferences_preset_handle.changed) {
  665. config_raw.keymap = box_preferences_files_keymap[box_preferences_preset_handle.position] + ".json";
  666. config_apply();
  667. config_load_keymap();
  668. }
  669. if (zui_button(tr("New"))) {
  670. ui_box_show_custom(function (ui: zui_t) {
  671. if (zui_tab(zui_handle(__ID__), tr("New Keymap"))) {
  672. let row: f32[] = [0.5, 0.5];
  673. zui_row(row);
  674. let h: zui_handle_t = zui_handle(__ID__);
  675. if (h.init) {
  676. h.text = "new_keymap";
  677. }
  678. let keymap_name: string = zui_text_input(h, tr("Name"));
  679. if (zui_button(tr("OK")) || ui.is_return_down) {
  680. let template: string = json_stringify(base_get_default_keymap());
  681. if (!ends_with(keymap_name, ".json")) {
  682. keymap_name += ".json";
  683. }
  684. let path: string = path_data() + path_sep + "keymap_presets" + path_sep + keymap_name;
  685. krom_file_save_bytes(path, sys_string_to_buffer(template));
  686. box_preferences_fetch_keymaps(); // Refresh file list
  687. config_raw.keymap = keymap_name;
  688. box_preferences_preset_handle.position = box_preferences_get_preset_index();
  689. ui_box_hide();
  690. box_preferences_htab.position = 5; // Keymap
  691. box_preferences_show();
  692. }
  693. }
  694. });
  695. }
  696. if (zui_button(tr("Import"))) {
  697. ui_files_show("json", false, false, function (path: string) {
  698. import_keymap_run(path);
  699. });
  700. }
  701. if (zui_button(tr("Export"))) {
  702. ui_files_show("json", true, false, function (dest: string) {
  703. if (!ends_with(ui_files_filename, ".json")) {
  704. ui_files_filename += ".json";
  705. }
  706. let path: string = path_data() + path_sep + "keymap_presets" + path_sep + config_raw.keymap;
  707. file_copy(path, dest + path_sep + ui_files_filename);
  708. });
  709. }
  710. zui_end_sticky();
  711. zui_separator(8, false);
  712. let index: i32 = 0;
  713. ui.changed = false;
  714. let keys: string[] = map_keys(config_keymap);
  715. for (let i: i32 = 0; i < keys.length; ++i) {
  716. let key: string = keys[i];
  717. let h: zui_handle_t = zui_nest(zui_handle(__ID__), index++);
  718. h.text = map_get(config_keymap, key);
  719. let text: string = zui_text_input(h, key, zui_align_t.LEFT);
  720. map_set(config_keymap, key, text);
  721. }
  722. if (ui.changed) {
  723. config_apply();
  724. config_save_keymap();
  725. }
  726. }
  727. if (zui_tab(box_preferences_htab, tr("Plugins"), true)) {
  728. zui_begin_sticky();
  729. let row: f32[] = [1 / 4, 1 / 4];
  730. zui_row(row);
  731. if (zui_button(tr("New"))) {
  732. ui_box_show_custom(function (ui: zui_t) {
  733. if (zui_tab(zui_handle(__ID__), tr("New Plugin"))) {
  734. let row: f32[] = [0.5, 0.5];
  735. zui_row(row);
  736. let h: zui_handle_t = zui_handle(__ID__);
  737. if (h.init) {
  738. h.text = "new_plugin";
  739. }
  740. let plugin_name: string = zui_text_input(h, tr("Name"));
  741. if (zui_button(tr("OK")) || ui.is_return_down) {
  742. let template: string =
  743. "let plugin = create();\
  744. let h1 = zui_handle_create();\
  745. plugin.draw_ui = function (ui) {\
  746. if (zui_panel(h1, \"New Plugin\")) {\
  747. if (zui_button(\"Button\")) {\
  748. console.error(\"Hello\");\
  749. }\
  750. }\
  751. }\
  752. ";
  753. if (!ends_with(plugin_name, ".js")) {
  754. plugin_name += ".js";
  755. }
  756. let path: string = path_data() + path_sep + "plugins" + path_sep + plugin_name;
  757. krom_file_save_bytes(path, sys_string_to_buffer(template));
  758. box_preferences_files_plugin = null; // Refresh file list
  759. ui_box_hide();
  760. box_preferences_htab.position = 6; // Plugins
  761. box_preferences_show();
  762. }
  763. }
  764. });
  765. }
  766. if (zui_button(tr("Import"))) {
  767. ui_files_show("js,zip", false, false, function (path: string) {
  768. import_plugin_run(path);
  769. });
  770. }
  771. zui_end_sticky();
  772. if (box_preferences_files_plugin == null) {
  773. box_preferences_fetch_plugins();
  774. }
  775. if (config_raw.plugins == null) {
  776. config_raw.plugins = [];
  777. }
  778. let h: zui_handle_t = zui_handle(__ID__);
  779. if (h.init) {
  780. h.selected = false;
  781. }
  782. for (let i: i32 = 0; i < box_preferences_files_plugin.length; ++i) {
  783. let f: string = box_preferences_files_plugin[i];
  784. let is_js: bool = ends_with(f, ".js");
  785. if (!is_js) {
  786. continue;
  787. }
  788. let enabled: bool = array_index_of(config_raw.plugins, f) >= 0;
  789. h.selected = enabled;
  790. let tag: string = is_js ? string_split(f, ".")[0] : f;
  791. zui_check(h, tag);
  792. if (h.changed && h.selected != enabled) {
  793. h.selected ? config_enable_plugin(f) : config_disable_plugin(f);
  794. base_redraw_ui();
  795. }
  796. if (ui.is_hovered && ui.input_released_r) {
  797. ui_menu_draw(function (ui: zui_t) {
  798. let path: string = path_data() + path_sep + "plugins" + path_sep + f;
  799. if (ui_menu_button(ui, tr("Edit in Text Editor"))) {
  800. file_start(path);
  801. }
  802. if (ui_menu_button(ui, tr("Edit in Script Tab"))) {
  803. let blob: buffer_t = data_get_blob("plugins/" + f);
  804. tab_script_hscript.text = sys_buffer_to_string(blob);
  805. data_delete_blob("plugins/" + f);
  806. console_info(tr("Script opened"));
  807. }
  808. if (ui_menu_button(ui, tr("Export"))) {
  809. ui_files_show("js", true, false, function (dest: string) {
  810. if (!ends_with(ui_files_filename, ".js")) {
  811. ui_files_filename += ".js";
  812. }
  813. let path: string = path_data() + path_sep + "plugins" + path_sep + f;
  814. file_copy(path, dest + path_sep + ui_files_filename);
  815. });
  816. }
  817. if (ui_menu_button(ui, tr("Delete"))) {
  818. if (array_index_of(config_raw.plugins, f) >= 0) {
  819. array_remove(config_raw.plugins, f);
  820. plugin_stop(f);
  821. }
  822. array_remove(box_preferences_files_plugin, f);
  823. file_delete(path);
  824. }
  825. }, 4);
  826. }
  827. }
  828. }
  829. }, 620, config_raw.touch_ui ? 480 : 420, function () {
  830. config_save();
  831. });
  832. }
  833. function box_preferences_fetch_themes() {
  834. box_preferences_themes = file_read_directory(path_data() + path_sep + "themes");
  835. for (let i: i32 = 0; i < box_preferences_themes.length; ++i) {
  836. box_preferences_themes[i] = substring(box_preferences_themes[i], 0, box_preferences_themes[i].length - 5); // Strip .json
  837. }
  838. box_preferences_themes.unshift("default");
  839. }
  840. function box_preferences_fetch_keymaps() {
  841. box_preferences_files_keymap = file_read_directory(path_data() + path_sep + "keymap_presets");
  842. for (let i: i32 = 0; i < box_preferences_files_keymap.length; ++i) {
  843. box_preferences_files_keymap[i] = substring(box_preferences_files_keymap[i], 0, box_preferences_files_keymap[i].length - 5); // Strip .json
  844. }
  845. box_preferences_files_keymap.unshift("default");
  846. }
  847. function box_preferences_fetch_plugins() {
  848. box_preferences_files_plugin = file_read_directory(path_data() + path_sep + "plugins");
  849. }
  850. function box_preferences_get_theme_index(): i32 {
  851. return array_index_of(box_preferences_themes, substring(config_raw.theme, 0, config_raw.theme.length - 5)); // Strip .json
  852. }
  853. function box_preferences_get_preset_index(): i32 {
  854. return array_index_of(box_preferences_files_keymap, substring(config_raw.keymap, 0, config_raw.keymap.length - 5)); // Strip .json
  855. }
  856. function box_preferences_set_scale() {
  857. let scale: f32 = config_raw.window_scale;
  858. zui_set_scale(ui_base_ui, scale);
  859. ui_header_h = math_floor(ui_header_default_h * scale);
  860. config_raw.layout[layout_size_t.STATUS_H] = math_floor(ui_status_default_status_h * scale);
  861. ui_menubar_w = math_floor(ui_menubar_default_w * scale);
  862. ui_base_set_icon_scale();
  863. zui_set_scale(ui_nodes_ui, scale);
  864. zui_set_scale(ui_view2d_ui, scale);
  865. zui_set_scale(base_ui_box, scale);
  866. zui_set_scale(base_ui_menu, scale);
  867. base_resize();
  868. ///if (is_paint || is_sculpt)
  869. config_raw.layout[layout_size_t.SIDEBAR_W] = math_floor(ui_base_default_sidebar_w * scale);
  870. ui_toolbar_w = math_floor(ui_toolbar_default_w * scale);
  871. ///end
  872. }