ui_header.ts 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629
  1. let ui_header_default_h: i32 = 28;
  2. let ui_header_h: i32 = ui_header_default_h;
  3. let ui_header_handle: zui_handle_t = zui_handle_create();
  4. let ui_header_worktab: zui_handle_t = zui_handle_create();
  5. function ui_header_init() {
  6. ui_header_handle.layout = zui_layout_t.HORIZONTAL;
  7. }
  8. function ui_header_render_ui() {
  9. let ui: zui_t = ui_base_ui;
  10. if (config_raw.touch_ui) {
  11. ui_header_h = ui_header_default_h + 6;
  12. }
  13. else {
  14. ui_header_h = ui_header_default_h;
  15. }
  16. ui_header_h = math_floor(ui_header_h * zui_SCALE(ui));
  17. if (config_raw.layout[layout_size_t.HEADER] == 0) {
  18. return;
  19. }
  20. let nodesw: i32 = (ui_nodes_show || ui_view2d_show) ? config_raw.layout[layout_size_t.NODES_W] : 0;
  21. ///if is_lab
  22. let ww: i32 = sys_width() - nodesw;
  23. ///else
  24. let ww: i32 = sys_width() - ui_toolbar_w - config_raw.layout[layout_size_t.SIDEBAR_W] - nodesw;
  25. ///end
  26. if (zui_window(ui_header_handle, app_x(), ui_header_h, ww, ui_header_h)) {
  27. ui._y += 2;
  28. ui_header_draw_tool_properties(ui);
  29. }
  30. }
  31. ///if is_paint
  32. let _ui_header_draw_tool_properties_h: zui_handle_t;
  33. function ui_header_draw_tool_properties(ui: zui_t) {
  34. if (context_raw.tool == workspace_tool_t.COLORID) {
  35. zui_text(tr("Picked Color"));
  36. if (context_raw.colorid_picked) {
  37. zui_image(map_get(render_path_render_targets, "texpaint_colorid")._image, 0xffffffff, 64);
  38. }
  39. ui.enabled = context_raw.colorid_picked;
  40. if (zui_button(tr("Clear"))) {
  41. context_raw.colorid_picked = false;
  42. ui_toolbar_handle.redraws = 1;
  43. }
  44. ui.enabled = true;
  45. zui_text(tr("Color ID Map"));
  46. if (project_asset_names.length > 0) {
  47. let cid: i32 = zui_combo(context_raw.colorid_handle, base_enum_texts("TEX_IMAGE"), tr("Color ID"));
  48. if (context_raw.colorid_handle.changed) {
  49. context_raw.ddirty = 2;
  50. context_raw.colorid_picked = false;
  51. ui_toolbar_handle.redraws = 1;
  52. }
  53. zui_image(project_get_image(project_assets[cid]));
  54. if (ui.is_hovered) {
  55. zui_tooltip_image(project_get_image(project_assets[cid]), 256);
  56. }
  57. }
  58. if (zui_button(tr("Import"))) {
  59. ui_files_show(path_texture_formats.join(","), false, true, function (path: string) {
  60. import_asset_run(path, -1.0, -1.0, true, false);
  61. context_raw.colorid_handle.position = project_asset_names.length - 1;
  62. for (let i: i32 = 0; i < project_assets.length; ++i) {
  63. let a: asset_t = project_assets[i];
  64. // Already imported
  65. if (a.file == path) {
  66. context_raw.colorid_handle.position = array_index_of(project_assets, a);
  67. }
  68. }
  69. context_raw.ddirty = 2;
  70. context_raw.colorid_picked = false;
  71. ui_toolbar_handle.redraws = 1;
  72. ui_base_hwnds[2].redraws = 2;
  73. });
  74. }
  75. ui.enabled = context_raw.colorid_picked;
  76. if (zui_button(tr("To Mask"))) {
  77. if (slot_layer_is_mask(context_raw.layer)) {
  78. context_set_layer(context_raw.layer.parent);
  79. }
  80. let m: slot_layer_t = base_new_mask(false, context_raw.layer);
  81. app_notify_on_next_frame(function (m: slot_layer_t) {
  82. if (base_pipe_merge == null) {
  83. base_make_pipe();
  84. }
  85. if (const_data_screen_aligned_vb == null) {
  86. const_data_create_screen_aligned_data();
  87. }
  88. g4_begin(m.texpaint);
  89. g4_set_pipeline(base_pipe_colorid_to_mask);
  90. g4_set_tex(base_texpaint_colorid,map_get(render_path_render_targets, "texpaint_colorid")._image);
  91. g4_set_tex(base_tex_colorid, project_get_image(project_assets[context_raw.colorid_handle.position]));
  92. g4_set_vertex_buffer(const_data_screen_aligned_vb);
  93. g4_set_index_buffer(const_data_screen_aligned_ib);
  94. g4_draw();
  95. g4_end();
  96. context_raw.colorid_picked = false;
  97. ui_toolbar_handle.redraws = 1;
  98. ui_header_handle.redraws = 1;
  99. context_raw.layer_preview_dirty = true;
  100. base_update_fill_layers();
  101. }, m);
  102. history_new_white_mask();
  103. }
  104. ui.enabled = true;
  105. }
  106. else if (context_raw.tool == workspace_tool_t.PICKER || context_raw.tool == workspace_tool_t.MATERIAL) {
  107. let base_r_picked: f32 = math_round(color_get_rb(context_raw.picked_color.base) / 255 * 10) / 10;
  108. let base_g_picked: f32 = math_round(color_get_gb(context_raw.picked_color.base) / 255 * 10) / 10;
  109. let base_b_picked: f32 = math_round(color_get_bb(context_raw.picked_color.base) / 255 * 10) / 10;
  110. let normal_r_picked: f32 = math_round(color_get_rb(context_raw.picked_color.normal) / 255 * 10) / 10;
  111. let normal_g_picked: f32 = math_round(color_get_gb(context_raw.picked_color.normal) / 255 * 10) / 10;
  112. let normal_b_picked: f32 = math_round(color_get_bb(context_raw.picked_color.normal) / 255 * 10) / 10;
  113. let occlusion_picked: f32 = math_round(context_raw.picked_color.occlusion * 100) / 100;
  114. let roughness_picked: f32 = math_round(context_raw.picked_color.roughness * 100) / 100;
  115. let metallic_picked: f32 = math_round(context_raw.picked_color.metallic * 100) / 100;
  116. let height_picked: f32 = math_round(context_raw.picked_color.height * 100) / 100;
  117. let opacity_picked: f32 = math_round(context_raw.picked_color.opacity * 100) / 100;
  118. let h: zui_handle_t = zui_handle(__ID__);
  119. let color: color_t = 0xffffffff;
  120. color = color_set_rb(color, base_r_picked * 255);
  121. color = color_set_gb(color, base_g_picked * 255);
  122. color = color_set_bb(color, base_b_picked * 255);
  123. h.color = color;
  124. let state: zui_state_t = zui_text("", 0, h.color);
  125. if (state == zui_state_t.STARTED) {
  126. let uix: i32 = ui._x;
  127. let uiy: i32 = ui._y;
  128. base_drag_off_x = -(mouse_x - uix - ui._window_x - 3);
  129. base_drag_off_y = -(mouse_y - uiy - ui._window_y + 1);
  130. base_drag_swatch = project_clone_swatch(context_raw.picked_color);
  131. }
  132. if (ui.is_hovered) {
  133. zui_tooltip(tr("Drag and drop picked color to swatches, materials, layers or to the node editor"));
  134. }
  135. if (ui.is_hovered && ui.input_released) {
  136. _ui_header_draw_tool_properties_h = h;
  137. ui_menu_draw(function (ui: zui_t) {
  138. zui_fill(0, 0, ui._w / zui_SCALE(ui), ui.ops.theme.ELEMENT_H * 9, ui.ops.theme.SEPARATOR_COL);
  139. ui.changed = false;
  140. zui_color_wheel(_ui_header_draw_tool_properties_h, false, null, 10 * ui.ops.theme.ELEMENT_H * zui_SCALE(ui), false);
  141. if (ui.changed) {
  142. ui_menu_keep_open = true;
  143. }
  144. }, 10);
  145. }
  146. if (zui_button(tr("Add Swatch"))) {
  147. let new_swatch: swatch_color_t = project_clone_swatch(context_raw.picked_color);
  148. context_set_swatch(new_swatch);
  149. array_push(project_raw.swatches, new_swatch);
  150. ui_base_hwnds[2].redraws = 1;
  151. }
  152. if (ui.is_hovered) {
  153. zui_tooltip(tr("Add picked color to swatches"));
  154. }
  155. zui_text(tr("Base") + " (" + base_r_picked + "," + base_g_picked + "," + base_b_picked + ")");
  156. zui_text(tr("Normal") + " (" + normal_r_picked + "," + normal_g_picked + "," + normal_b_picked + ")");
  157. zui_text(tr("Occlusion") + " (" + occlusion_picked + ")");
  158. zui_text(tr("Roughness") + " (" + roughness_picked + ")");
  159. zui_text(tr("Metallic") + " (" + metallic_picked + ")");
  160. zui_text(tr("Height") + " (" + height_picked + ")");
  161. zui_text(tr("Opacity") + " (" + opacity_picked + ")");
  162. let h_select_mat: zui_handle_t = zui_handle(__ID__);
  163. if (h_select_mat.init) {
  164. h_select_mat.selected = context_raw.picker_select_material;
  165. }
  166. context_raw.picker_select_material = zui_check(h_select_mat, tr("Select Material"));
  167. let picker_mask_combo: string[] = [tr("None"), tr("Material")];
  168. zui_combo(context_raw.picker_mask_handle, picker_mask_combo, tr("Mask"), true);
  169. if (context_raw.picker_mask_handle.changed) {
  170. make_material_parse_paint_material();
  171. }
  172. }
  173. else if (context_raw.tool == workspace_tool_t.BAKE) {
  174. ui.changed = false;
  175. ///if (krom_direct3d12 || krom_vulkan || krom_metal)
  176. let baking: bool = context_raw.pdirty > 0;
  177. let rt_bake: bool = context_raw.bake_type == bake_type_t.AO || context_raw.bake_type == bake_type_t.LIGHTMAP || context_raw.bake_type == bake_type_t.BENT_NORMAL || context_raw.bake_type == bake_type_t.THICKNESS;
  178. if (baking && zui_button(tr("Stop"))) {
  179. context_raw.pdirty = 0;
  180. context_raw.rdirty = 2;
  181. }
  182. ///else
  183. let baking: bool = false;
  184. let rt_bake: bool = false;
  185. ///end
  186. if (!baking && zui_button(tr("Bake"))) {
  187. context_raw.pdirty = rt_bake ? context_raw.bake_samples : 1;
  188. context_raw.rdirty = 3;
  189. app_notify_on_next_frame(function () {
  190. context_raw.layer_preview_dirty = true;
  191. });
  192. ui_base_hwnds[0].redraws = 2;
  193. history_push_undo = true;
  194. ///if (krom_direct3d12 || krom_vulkan || krom_metal)
  195. render_path_raytrace_bake_current_sample = 0;
  196. ///end
  197. }
  198. let bake_handle: zui_handle_t = zui_handle(__ID__);
  199. if (bake_handle.init) {
  200. bake_handle.position = context_raw.bake_type;
  201. }
  202. let bakes: string[] = [
  203. tr("AO"),
  204. tr("Curvature"),
  205. tr("Normal"),
  206. tr("Object Normal"),
  207. tr("Height"),
  208. tr("Derivative"),
  209. tr("Position"),
  210. tr("TexCoord"),
  211. tr("Material ID"),
  212. tr("Object ID"),
  213. tr("Vertex Color"),
  214. ];
  215. ///if (krom_direct3d12 || krom_vulkan || krom_metal)
  216. if (krom_raytrace_supported()) {
  217. array_push(bakes, tr("Lightmap"));
  218. array_push(bakes, tr("Bent Normal"));
  219. array_push(bakes, tr("Thickness"));
  220. }
  221. else {
  222. bakes.shift(); // Remove AO
  223. }
  224. ///end
  225. context_raw.bake_type = zui_combo(bake_handle, bakes, tr("Bake"));
  226. ///if (krom_direct3d12 || krom_vulkan || krom_metal)
  227. if (!krom_raytrace_supported()) {
  228. context_raw.bake_type += 1; // Offset for removed AO
  229. }
  230. ///end
  231. ///if (krom_direct3d12 || krom_vulkan || krom_metal)
  232. if (rt_bake) {
  233. let samples_handle: zui_handle_t = zui_handle(__ID__);
  234. if (samples_handle.init) {
  235. samples_handle.value = context_raw.bake_samples;
  236. }
  237. context_raw.bake_samples = math_floor(zui_slider(samples_handle, tr("Samples"), 1, 512, true, 1));
  238. }
  239. ///end
  240. if (context_raw.bake_type == bake_type_t.NORMAL_OBJECT || context_raw.bake_type == bake_type_t.POSITION || context_raw.bake_type == bake_type_t.BENT_NORMAL) {
  241. let bake_up_axis_handle: zui_handle_t = zui_handle(__ID__);
  242. if (bake_up_axis_handle.init) {
  243. bake_up_axis_handle.position = context_raw.bake_up_axis;
  244. }
  245. let bake_up_axis_combo: string[] = [tr("Z"), tr("Y")];
  246. context_raw.bake_up_axis = zui_combo(bake_up_axis_handle, bake_up_axis_combo, tr("Up Axis"), true);
  247. }
  248. if (context_raw.bake_type == bake_type_t.AO || context_raw.bake_type == bake_type_t.CURVATURE) {
  249. let bake_axis_handle: zui_handle_t = zui_handle(__ID__);
  250. if (bake_axis_handle.init) {
  251. bake_axis_handle.position = context_raw.bake_axis;
  252. }
  253. let bake_axis_combo: string[] = [tr("XYZ"), tr("X"), tr("Y"), tr("Z"), tr("-X"), tr("-Y"), tr("-Z")];
  254. context_raw.bake_axis = zui_combo(bake_axis_handle, bake_axis_combo, tr("Axis"), true);
  255. }
  256. if (context_raw.bake_type == bake_type_t.AO) {
  257. let strength_handle: zui_handle_t = zui_handle(__ID__);
  258. if (strength_handle.init) {
  259. strength_handle.value = context_raw.bake_ao_strength;
  260. }
  261. context_raw.bake_ao_strength = zui_slider(strength_handle, tr("Strength"), 0.0, 2.0, true);
  262. let radius_handle: zui_handle_t = zui_handle(__ID__);
  263. if (radius_handle.init) {
  264. radius_handle.value = context_raw.bake_ao_radius;
  265. }
  266. context_raw.bake_ao_radius = zui_slider(radius_handle, tr("Radius"), 0.0, 2.0, true);
  267. let offset_handle: zui_handle_t = zui_handle(__ID__);
  268. if (offset_handle.init) {
  269. offset_handle.value = context_raw.bake_ao_offset;
  270. }
  271. context_raw.bake_ao_offset = zui_slider(offset_handle, tr("Offset"), 0.0, 2.0, true);
  272. }
  273. ///if (krom_direct3d12 || krom_vulkan || krom_metal)
  274. if (rt_bake) {
  275. let progress: f32 = render_path_raytrace_bake_current_sample / context_raw.bake_samples;
  276. if (progress > 1.0) progress = 1.0;
  277. // Progress bar
  278. g2_set_color(ui.ops.theme.SEPARATOR_COL);
  279. zui_draw_rect(true, ui._x + 1, ui._y, ui._w - 2, zui_ELEMENT_H(ui));
  280. g2_set_color(ui.ops.theme.HIGHLIGHT_COL);
  281. zui_draw_rect(true, ui._x + 1, ui._y, (ui._w - 2) * progress, zui_ELEMENT_H(ui));
  282. g2_set_color(0xffffffff);
  283. zui_text(tr("Samples") + ": " + render_path_raytrace_bake_current_sample);
  284. zui_text(tr("Rays/pixel") + ": " + render_path_raytrace_bake_rays_pix);
  285. zui_text(tr("Rays/second") + ": " + render_path_raytrace_bake_rays_sec);
  286. }
  287. ///end
  288. if (context_raw.bake_type == bake_type_t.CURVATURE) {
  289. let strength_handle: zui_handle_t = zui_handle(__ID__);
  290. if (strength_handle.init) {
  291. strength_handle.value = context_raw.bake_curv_strength;
  292. }
  293. context_raw.bake_curv_strength = zui_slider(strength_handle, tr("Strength"), 0.0, 2.0, true);
  294. let radius_handle: zui_handle_t = zui_handle(__ID__);
  295. if (radius_handle.init) {
  296. radius_handle.value = context_raw.bake_curv_radius;
  297. }
  298. context_raw.bake_curv_radius = zui_slider(radius_handle, tr("Radius"), 0.0, 2.0, true);
  299. let offset_handle: zui_handle_t = zui_handle(__ID__);
  300. if (offset_handle.init) {
  301. offset_handle.value = context_raw.bake_curv_offset;
  302. }
  303. context_raw.bake_curv_offset = zui_slider(offset_handle, tr("Offset"), -2.0, 2.0, true);
  304. let smooth_handle: zui_handle_t = zui_handle(__ID__);
  305. if (smooth_handle.init) {
  306. smooth_handle.value = context_raw.bake_curv_smooth;
  307. }
  308. context_raw.bake_curv_smooth = math_floor(zui_slider(smooth_handle, tr("Smooth"), 0, 5, false, 1));
  309. }
  310. if (context_raw.bake_type == bake_type_t.NORMAL || context_raw.bake_type == bake_type_t.HEIGHT || context_raw.bake_type == bake_type_t.DERIVATIVE) {
  311. let ar: string[] = [];
  312. for (let i: i32 = 0; i < project_paint_objects.length; ++i) {
  313. let p: mesh_object_t = project_paint_objects[i];
  314. array_push(ar, p.base.name);
  315. }
  316. let poly_handle: zui_handle_t = zui_handle(__ID__);
  317. if (poly_handle.init) {
  318. poly_handle.position = context_raw.bake_high_poly;
  319. }
  320. context_raw.bake_high_poly = zui_combo(poly_handle, ar, tr("High Poly"));
  321. }
  322. if (ui.changed) {
  323. make_material_parse_paint_material();
  324. }
  325. }
  326. else if (context_raw.tool == workspace_tool_t.BRUSH ||
  327. context_raw.tool == workspace_tool_t.ERASER ||
  328. context_raw.tool == workspace_tool_t.FILL ||
  329. context_raw.tool == workspace_tool_t.DECAL ||
  330. context_raw.tool == workspace_tool_t.TEXT ||
  331. context_raw.tool == workspace_tool_t.CLONE ||
  332. context_raw.tool == workspace_tool_t.BLUR ||
  333. context_raw.tool == workspace_tool_t.SMUDGE ||
  334. context_raw.tool == workspace_tool_t.PARTICLE) {
  335. let decal: bool = context_raw.tool == workspace_tool_t.DECAL || context_raw.tool == workspace_tool_t.TEXT;
  336. let decal_mask: bool = decal && operator_shortcut(map_get(config_keymap, "decal_mask"), shortcut_type_t.DOWN);
  337. if (context_raw.tool != workspace_tool_t.FILL) {
  338. if (decal_mask) {
  339. context_raw.brush_decal_mask_radius = zui_slider(context_raw.brush_decal_mask_radius_handle, tr("Radius"), 0.01, 2.0, true);
  340. if (ui.is_hovered) {
  341. let vars: map_t<string, string> = map_create();
  342. map_set(vars, "brush_radius", map_get(config_keymap, "brush_radius"));
  343. map_set(vars, "brush_radius_decrease", map_get(config_keymap, "brush_radius_decrease"));
  344. map_set(vars, "brush_radius_increase", map_get(config_keymap, "brush_radius_increase"));
  345. zui_tooltip(tr("Hold {brush_radius} and move mouse to the left or press {brush_radius_decrease} to decrease the radius\nHold {brush_radius} and move mouse to the right or press {brush_radius_increase} to increase the radius", vars));
  346. }
  347. }
  348. else {
  349. context_raw.brush_radius = zui_slider(context_raw.brush_radius_handle, tr("Radius"), 0.01, 2.0, true);
  350. if (ui.is_hovered) {
  351. let vars: map_t<string, string> = map_create();
  352. map_set(vars, "brush_radius", map_get(config_keymap, "brush_radius"));
  353. map_set(vars, "brush_radius_decrease", map_get(config_keymap, "brush_radius_decrease"));
  354. map_set(vars, "brush_radius_increase", map_get(config_keymap, "brush_radius_increase"));
  355. zui_tooltip(tr("Hold {brush_radius} and move mouse to the left or press {brush_radius_decrease} to decrease the radius\nHold {brush_radius} and move mouse to the right or press {brush_radius_increase} to increase the radius", vars));
  356. }
  357. }
  358. }
  359. if (context_raw.tool == workspace_tool_t.DECAL || context_raw.tool == workspace_tool_t.TEXT) {
  360. context_raw.brush_scale_x = zui_slider(context_raw.brush_scale_x_handle, tr("Scale X"), 0.01, 2.0, true);
  361. }
  362. if (context_raw.tool == workspace_tool_t.BRUSH ||
  363. context_raw.tool == workspace_tool_t.FILL ||
  364. context_raw.tool == workspace_tool_t.DECAL ||
  365. context_raw.tool == workspace_tool_t.TEXT) {
  366. let brush_scale_handle: zui_handle_t = zui_handle(__ID__);
  367. if (brush_scale_handle.init) {
  368. brush_scale_handle.value = context_raw.brush_scale;
  369. }
  370. context_raw.brush_scale = zui_slider(brush_scale_handle, tr("UV Scale"), 0.01, 5.0, true);
  371. if (brush_scale_handle.changed) {
  372. if (context_raw.tool == workspace_tool_t.DECAL || context_raw.tool == workspace_tool_t.TEXT) {
  373. let current: image_t = _g2_current;
  374. g2_end();
  375. util_render_make_decal_preview();
  376. g2_begin(current);
  377. }
  378. }
  379. context_raw.brush_angle = zui_slider(context_raw.brush_angle_handle, tr("Angle"), 0.0, 360.0, true, 1);
  380. if (ui.is_hovered) {
  381. let vars: map_t<string, string> = map_create();
  382. map_set(vars, "brush_angle", map_get(config_keymap, "brush_angle"));
  383. zui_tooltip(tr("Hold {brush_angle} and move mouse to the left to decrease the angle\nHold {brush_angle} and move mouse to the right to increase the angle", vars));
  384. }
  385. if (context_raw.brush_angle_handle.changed) {
  386. make_material_parse_paint_material();
  387. }
  388. }
  389. context_raw.brush_opacity = zui_slider(context_raw.brush_opacity_handle, tr("Opacity"), 0.0, 1.0, true);
  390. if (ui.is_hovered) {
  391. let vars: map_t<string, string> = map_create();
  392. map_set(vars, "brush_opacity", map_get(config_keymap, "brush_opacity"));
  393. zui_tooltip(tr("Hold {brush_opacity} and move mouse to the left to decrease the opacity\nHold {brush_opacity} and move mouse to the right to increase the opacity", vars));
  394. }
  395. if (context_raw.tool == workspace_tool_t.BRUSH || context_raw.tool == workspace_tool_t.ERASER || context_raw.tool == workspace_tool_t.CLONE || decal_mask) {
  396. let h: zui_handle_t = zui_handle(__ID__);
  397. if (h.init) {
  398. h.value = context_raw.brush_hardness;
  399. }
  400. context_raw.brush_hardness = zui_slider(h, tr("Hardness"), 0.0, 1.0, true);
  401. }
  402. if (context_raw.tool != workspace_tool_t.ERASER) {
  403. let brush_blending_handle: zui_handle_t = zui_handle(__ID__);
  404. if (brush_blending_handle.init) {
  405. brush_blending_handle.value = context_raw.brush_blending;
  406. }
  407. let brush_blending_combo: string[] = [
  408. tr("Mix"),
  409. tr("Darken"),
  410. tr("Multiply"),
  411. tr("Burn"),
  412. tr("Lighten"),
  413. tr("Screen"),
  414. tr("Dodge"),
  415. tr("Add"),
  416. tr("Overlay"),
  417. tr("Soft Light"),
  418. tr("Linear Light"),
  419. tr("Difference"),
  420. tr("Subtract"),
  421. tr("Divide"),
  422. tr("Hue"),
  423. tr("Saturation"),
  424. tr("Color"),
  425. tr("Value"),
  426. ];
  427. context_raw.brush_blending = zui_combo(brush_blending_handle, brush_blending_combo, tr("Blending"));
  428. if (brush_blending_handle.changed) {
  429. make_material_parse_paint_material();
  430. }
  431. }
  432. if (context_raw.tool == workspace_tool_t.BRUSH || context_raw.tool == workspace_tool_t.FILL) {
  433. let paint_handle: zui_handle_t = zui_handle(__ID__);
  434. let texcoord_combo: string[] = [tr("UV Map"), tr("Triplanar"), tr("Project")];
  435. context_raw.brush_paint = zui_combo(paint_handle, texcoord_combo, tr("TexCoord"));
  436. if (paint_handle.changed) {
  437. make_material_parse_paint_material();
  438. }
  439. }
  440. if (context_raw.tool == workspace_tool_t.TEXT) {
  441. let h: zui_handle_t = zui_handle(__ID__);
  442. h.text = context_raw.text_tool_text;
  443. let w: i32 = ui._w;
  444. if (ui.text_selected_handle_ptr == h.ptr || ui.submit_text_handle_ptr == h.ptr) {
  445. ui._w *= 3;
  446. }
  447. context_raw.text_tool_text = zui_text_input(h, "", zui_align_t.LEFT, true, true);
  448. ui._w = w;
  449. if (h.changed) {
  450. let current: image_t = _g2_current;
  451. g2_end();
  452. util_render_make_text_preview();
  453. util_render_make_decal_preview();
  454. g2_begin(current);
  455. }
  456. }
  457. if (context_raw.tool == workspace_tool_t.FILL) {
  458. let fill_mode_combo: string[] = [tr("Object"), tr("Face"), tr("Angle"), tr("UV Island")];
  459. zui_combo(context_raw.fill_type_handle, fill_mode_combo, tr("Fill Mode"));
  460. if (context_raw.fill_type_handle.changed) {
  461. if (context_raw.fill_type_handle.position == fill_type_t.FACE) {
  462. let current: image_t = _g2_current;
  463. g2_end();
  464. // cacheUVMap();
  465. util_uv_cache_triangle_map();
  466. g2_begin(current);
  467. // wireframeHandle.selected = drawWireframe = true;
  468. }
  469. make_material_parse_paint_material();
  470. make_material_parse_mesh_material();
  471. }
  472. }
  473. else {
  474. let _w: i32 = ui._w;
  475. let sc: f32 = zui_SCALE(ui);
  476. let touch_header: bool = (config_raw.touch_ui && config_raw.layout[layout_size_t.HEADER] == 1);
  477. if (touch_header) {
  478. ui._x -= 4 * sc;
  479. }
  480. ui._w = math_floor((touch_header ? 54 : 60) * sc);
  481. let xray_handle: zui_handle_t = zui_handle(__ID__);
  482. if (xray_handle.init) {
  483. xray_handle.selected = context_raw.xray;
  484. }
  485. context_raw.xray = zui_check(xray_handle, tr("X-Ray"));
  486. if (xray_handle.changed) {
  487. make_material_parse_paint_material();
  488. }
  489. let sym_x_handle: zui_handle_t = zui_handle(__ID__);
  490. if (sym_x_handle.init) {
  491. sym_x_handle.selected = false;
  492. }
  493. let sym_y_handle: zui_handle_t = zui_handle(__ID__);
  494. if (sym_y_handle.init) {
  495. sym_y_handle.selected = false;
  496. }
  497. let sym_z_handle: zui_handle_t = zui_handle(__ID__);
  498. if (sym_z_handle.init) {
  499. sym_z_handle.selected = false;
  500. }
  501. if (config_raw.layout[layout_size_t.HEADER] == 1) {
  502. if (config_raw.touch_ui) {
  503. ui._w = math_floor(19 * sc);
  504. context_raw.sym_x = zui_check(sym_x_handle, "");
  505. ui._x -= 4 * sc;
  506. context_raw.sym_y = zui_check(sym_y_handle, "");
  507. ui._x -= 4 * sc;
  508. context_raw.sym_z = zui_check(sym_z_handle, "");
  509. ui._x -= 4 * sc;
  510. ui._w = math_floor(40 * sc);
  511. zui_text(tr("X") + tr("Y") + tr("Z"));
  512. }
  513. else {
  514. ui._w = math_floor(56 * sc);
  515. zui_text(tr("Symmetry"));
  516. ui._w = math_floor(25 * sc);
  517. context_raw.sym_x = zui_check(sym_x_handle, tr("X"));
  518. context_raw.sym_y = zui_check(sym_y_handle, tr("Y"));
  519. context_raw.sym_z = zui_check(sym_z_handle, tr("Z"));
  520. }
  521. ui._w = _w;
  522. }
  523. else {
  524. // Popup
  525. ui._w = _w;
  526. context_raw.sym_x = zui_check(sym_x_handle, tr("Symmetry") + " " + tr("X"));
  527. context_raw.sym_y = zui_check(sym_y_handle, tr("Symmetry") + " " + tr("Y"));
  528. context_raw.sym_z = zui_check(sym_z_handle, tr("Symmetry") + " " + tr("Z"));
  529. }
  530. if (sym_x_handle.changed || sym_y_handle.changed || sym_z_handle.changed) {
  531. make_material_parse_paint_material();
  532. }
  533. }
  534. ///if arm_physics
  535. if (context_raw.tool == workspace_tool_t.PARTICLE) {
  536. ui._x += 10 * zui_SCALE(ui);
  537. let phys_handle: zui_handle_t = zui_handle(__ID__);
  538. if (phys_handle.init) {
  539. phys_handle.selected = false;
  540. }
  541. context_raw.particle_physics = zui_check(phys_handle, tr("Physics"));
  542. if (phys_handle.changed) {
  543. util_particle_init_physics();
  544. make_material_parse_paint_material();
  545. }
  546. }
  547. ///end
  548. }
  549. }
  550. ///end
  551. ///if is_sculpt
  552. function ui_header_draw_tool_properties(ui: zui_t) {
  553. if (context_raw.tool == workspace_tool_t.BRUSH) {
  554. context_raw.brush_radius = zui_slider(context_raw.brush_radius_handle, tr("Radius"), 0.01, 2.0, true);
  555. if (ui.is_hovered) {
  556. let vars: map_t<string, string> = map_create();
  557. map_set(vars, "brush_radius", map_get(config_keymap, "brush_radius"));
  558. map_set(vars, "brush_radius_decrease", map_get(config_keymap, "brush_radius_decrease"));
  559. map_set(vars, "brush_radius_increase", map_get(config_keymap, "brush_radius_increase"));
  560. zui_tooltip(tr("Hold {brush_radius} and move mouse to the left or press {brush_radius_decrease} to decrease the radius\nHold {brush_radius} and move mouse to the right or press {brush_radius_increase} to increase the radius", vars));
  561. }
  562. }
  563. }
  564. ///end
  565. ///if is_lab
  566. function ui_header_draw_tool_properties(ui: zui_t) {
  567. if (context_raw.tool == workspace_tool_t.PICKER) {
  568. }
  569. else if (context_raw.tool == workspace_tool_t.ERASER ||
  570. context_raw.tool == workspace_tool_t.CLONE ||
  571. context_raw.tool == workspace_tool_t.BLUR ||
  572. context_raw.tool == workspace_tool_t.SMUDGE) {
  573. let nodes: zui_nodes_t = ui_nodes_get_nodes();
  574. let canvas: zui_node_canvas_t = ui_nodes_get_canvas(true);
  575. let inpaint: bool = nodes.nodes_selected_id.length > 0 && zui_get_node(canvas.nodes, nodes.nodes_selected_id[0]).type == "InpaintNode";
  576. if (inpaint) {
  577. context_raw.brush_radius = zui_slider(context_raw.brush_radius_handle, tr("Radius"), 0.01, 2.0, true);
  578. if (ui.is_hovered) {
  579. let vars: map_t<string, string> = map_create();
  580. map_set(vars, "brush_radius", map_get(config_keymap, "brush_radius"));
  581. map_set(vars, "brush_radius_decrease", map_get(config_keymap, "brush_radius_decrease"));
  582. map_set(vars, "brush_radius_increase", map_get(config_keymap, "brush_radius_increase"));
  583. zui_tooltip(tr("Hold {brush_radius} and move mouse to the left or press {brush_radius_decrease} to decrease the radius\nHold {brush_radius} and move mouse to the right or press {brush_radius_increase} to increase the radius", vars));
  584. }
  585. }
  586. }
  587. }
  588. ///end