luboslenco 1 rok temu
rodzic
commit
a76a275a36

+ 123 - 116
armorforge/Sources/tab_objects.ts

@@ -1,135 +1,142 @@
 
 let tab_objects_material_id: i32 = 0;
+let tab_objects_line_counter: i32 = 0;
 
 function tab_objects_roundfp(f: f32, precision: i32 = 2): f32 {
 	f *= math_pow(10, precision);
 	return math_round(f) / math_pow(10, precision);
 }
 
-function tab_objects_draw(htab: zui_handle_t) {
-	let ui = ui_base_ui;
-	if (zui_tab(htab, tr("Objects"))) {
-		zui_begin_sticky();
-		zui_row([1 / 4]);
-		if (zui_button("Import")) {
-			project_import_mesh(false, function () {
-				object_set_parent(project_paint_objects.pop().base, null);
-			});
+function tab_objects_import_mesh_done() {
+	object_set_parent(project_paint_objects.pop().base, null);
+}
+
+function tab_objects_draw_menu(ui: zui_t) {
+	if (ui_menu_button(ui, "Assign Material")) {
+		tab_objects_material_id++;
+
+		for (let i: i32 = 0; i < _scene_raw.shader_datas.length; ++i) {
+			let sh: shader_data_t = _scene_raw.shader_datas[i];
+			if (sh.name == "Material_data") {
+				let s: shader_data_t = json_parse(json_stringify(sh));
+				s.name = "TempMaterial_data" + tab_objects_material_id;
+				array_push(_scene_raw.shader_datas, s);
+				break;
+			}
 		}
-		zui_end_sticky();
 
-		if (zui_panel(zui_handle("tabobjects_0", {selected: true}), "Outliner")) {
-			// ui.indent();
-			ui._y -= zui_ELEMENT_OFFSET(ui);
+		for (let i: i32 = 0; i < _scene_raw.material_datas.length; ++i) {
+			let mat: material_data_t = _scene_raw.material_datas[i];
+			if (mat.name == "Material") {
+				let m: material_data_t = json_parse(json_stringify(mat));
+				m.name = "TempMaterial" + tab_objects_material_id;
+				m.shader = "TempMaterial_data" + tab_objects_material_id;
+				array_push(_scene_raw.material_datas, m);
+				break;
+			}
+		}
 
-			let line_counter = 0;
-			let draw_list = function (list_handle: zui_handle_t, current_object: object_t) {
-				if (char_at(current_object.name, 0) == ".") {
-					return; // Hidden
-				}
-				let b: bool = false;
+		let md: material_data_t = data_get_material("Scene", "TempMaterial" + tab_objects_material_id);
+		let mo: mesh_object_t = current_object.ext;
+		mo.materials = [md];
+		make_material_parse_mesh_preview_material(md);
+	}
+}
 
-				// Highlight every other line
-				if (line_counter % 2 == 0) {
-					g2_set_color(ui.t.SEPARATOR_COL);
-					g2_fill_rect(0, ui._y, ui._window_w, zui_ELEMENT_H(ui));
-					g2_set_color(0xffffffff);
-				}
+function tab_objects_draw_list(list_handle: zui_handle_t, current_object: object_t) {
+	if (char_at(current_object.name, 0) == ".") {
+		return; // Hidden
+	}
+	let b: bool = false;
 
-				// Highlight selected line
-				if (current_object == context_context_raw.selected_object) {
-					g2_set_color(0xff205d9c);
-					g2_fill_rect(0, ui._y, ui._window_w, zui_ELEMENT_H(ui));
-					g2_set_color(0xffffffff);
-				}
+	// Highlight every other line
+	if (tab_objects_line_counter % 2 == 0) {
+		g2_set_color(ui.t.SEPARATOR_COL);
+		g2_fill_rect(0, ui._y, ui._window_w, zui_ELEMENT_H(ui));
+		g2_set_color(0xffffffff);
+	}
 
-				if (current_object.children.length > 0) {
-					zui_row([1 / 13, 12 / 13]);
-					b = zui_panel(zui_nest(list_handle, line_counter, {selected: true}), "", true, false, false);
-					zui_text(current_object.name);
-				}
-				else {
-					ui._x += 18; // Sign offset
+	// Highlight selected line
+	if (current_object == context_context_raw.selected_object) {
+		g2_set_color(0xff205d9c);
+		g2_fill_rect(0, ui._y, ui._window_w, zui_ELEMENT_H(ui));
+		g2_set_color(0xffffffff);
+	}
 
-					// Draw line that shows parent relations
-					g2_set_color(ui.t.ACCENT_COL);
-					g2_draw_line(ui._x - 10, ui._y + zui_ELEMENT_H(ui) / 2, ui._x, ui._y + zui_ELEMENT_H(ui) / 2);
-					g2_set_color(0xffffffff);
+	if (current_object.children.length > 0) {
+		zui_row([1 / 13, 12 / 13]);
+		b = zui_panel(zui_nest(list_handle, tab_objects_line_counter, {selected: true}), "", true, false, false);
+		zui_text(current_object.name);
+	}
+	else {
+		ui._x += 18; // Sign offset
 
-					zui_text(current_object.name);
-					ui._x -= 18;
-				}
+		// Draw line that shows parent relations
+		g2_set_color(ui.t.ACCENT_COL);
+		g2_draw_line(ui._x - 10, ui._y + zui_ELEMENT_H(ui) / 2, ui._x, ui._y + zui_ELEMENT_H(ui) / 2);
+		g2_set_color(0xffffffff);
 
-				line_counter++;
-				// Undo applied offset for row drawing caused by end_element()
-				ui._y -= zui_ELEMENT_OFFSET(ui);
+		zui_text(current_object.name);
+		ui._x -= 18;
+	}
 
-				if (ui.is_released) {
-					context_context_raw.selected_object = current_object;
-				}
+	tab_objects_line_counter++;
+	// Undo applied offset for row drawing caused by end_element()
+	ui._y -= zui_ELEMENT_OFFSET(ui);
 
-				if (ui.is_hovered && ui.input_released_r) {
-					ui_menu_draw(function (ui: zui_t) {
-						if (ui_menu_button(ui, "Assign Material")) {
-							tab_objects_material_id++;
-
-							for (let i: i32 = 0; i < _scene_raw.shader_datas.length; ++i) {
-								let sh: shader_data_t = _scene_raw.shader_datas[i];
-								if (sh.name == "Material_data") {
-									let s: shader_data_t = json_parse(json_stringify(sh));
-									s.name = "TempMaterial_data" + tab_objects_material_id;
-									array_push(_scene_raw.shader_datas, s);
-									break;
-								}
-							}
-
-							for (let i: i32 = 0; i < _scene_raw.material_datas.length; ++i) {
-								let mat: material_data_t = _scene_raw.material_datas[i];
-								if (mat.name == "Material") {
-									let m: material_data_t = json_parse(json_stringify(mat));
-									m.name = "TempMaterial" + tab_objects_material_id;
-									m.shader = "TempMaterial_data" + tab_objects_material_id;
-									array_push(_scene_raw.material_datas, m);
-									break;
-								}
-							}
-
-							let md: material_data_t = data_get_material("Scene", "TempMaterial" + tab_objects_material_id);
-							let mo: mesh_object_t = current_object.ext;
-							mo.materials = [md];
-							make_material_parse_mesh_preview_material(md);
-						}
-					}, 1);
-				}
+	if (ui.is_released) {
+		context_context_raw.selected_object = current_object;
+	}
 
-				if (b) {
-					let current_y = ui._y;
-					for (let i: i32 = 0; i < current_object.children.length; ++i) {
-						let child: object_t = current_object.children[i];
-						// ui.indent();
-						draw_list(list_handle, child);
-						// ui.unindent();
-					}
+	if (ui.is_hovered && ui.input_released_r) {
+		ui_menu_draw(tab_objects_draw_menu, 1);
+	}
+
+	if (b) {
+		let current_y = ui._y;
+		for (let i: i32 = 0; i < current_object.children.length; ++i) {
+			let child: object_t = current_object.children[i];
+			// ui.indent();
+			tab_objects_draw_list(list_handle, child);
+			// ui.unindent();
+		}
+
+		// Draw line that shows parent relations
+		g2_set_color(ui.t.ACCENT_COL);
+		g2_draw_line(ui._x + 14, current_y, ui._x + 14, ui._y - zui_ELEMENT_H(ui) / 2);
+		g2_set_color(0xffffffff);
+	}
+}
+
+function tab_objects_draw(htab: zui_handle_t) {
+	let ui = ui_base_ui;
+	if (zui_tab(htab, tr("Objects"))) {
+		zui_begin_sticky();
+		zui_row([1 / 4]);
+		if (zui_button("Import")) {
+			project_import_mesh(false, tab_objects_import_mesh_done);
+		}
+		zui_end_sticky();
+
+		if (zui_panel(zui_handle(__ID__, {selected: true}), "Outliner")) {
+			// ui.indent();
+			ui._y -= zui_ELEMENT_OFFSET(ui);
+
+			tab_objects_line_counter = 0;
 
-					// Draw line that shows parent relations
-					g2_set_color(ui.t.ACCENT_COL);
-					g2_draw_line(ui._x + 14, current_y, ui._x + 14, ui._y - zui_ELEMENT_H(ui) / 2);
-					g2_set_color(0xffffffff);
-				}
-			}
 			for (let i: i32 = 0; i < _scene_root.children.length) {
 				let c: object_t = _scene_root.children[i];
-				draw_list(zui_handle("tabobjects_1"), c);
+				tab_objects_draw_list(zui_handle(__ID__), c);
 			}
 
 			// ui.unindent();
 		}
 
-		if (zui_panel(zui_handle("tabobjects_2", {selected: true}), "Properties")) {
+		if (zui_panel(zui_handle(__ID__, {selected: true}), "Properties")) {
 			// ui.indent();
 
 			if (context_context_raw.selected_object != null) {
-				let h = zui_handle("tabobjects_3");
+				let h = zui_handle(__ID__);
 				h.selected = context_context_raw.selected_object.visible;
 				context_context_raw.selected_object.visible = zui_check(h, "Visible");
 
@@ -144,21 +151,21 @@ function tab_objects_draw(htab: zui_handle_t) {
 				zui_row([1 / 4, 1 / 4, 1 / 4, 1 / 4]);
 				zui_text("Loc");
 
-				h = zui_handle("tabobjects_4");
+				h = zui_handle(__ID__);
 				h.text = roundfp(local_pos.x) + "";
 				f = parse_float(zui_text_input(h, "X"));
 				if (h.changed) {
 					local_pos.x = f;
 				}
 
-				h = zui_handle("tabobjects_5");
+				h = zui_handle(__ID__);
 				h.text = roundfp(local_pos.y) + "";
 				f = parse_float(zui_text_input(h, "Y"));
 				if (h.changed) {
 					local_pos.y = f;
 				}
 
-				h = zui_handle("tabobjects_6");
+				h = zui_handle(__ID__);
 				h.text = roundfp(local_pos.z) + "";
 				f = parse_float(zui_text_input(h, "Z"));
 				if (h.changed) {
@@ -168,7 +175,7 @@ function tab_objects_draw(htab: zui_handle_t) {
 				zui_row([1 / 4, 1 / 4, 1 / 4, 1 / 4]);
 				zui_text("Rotation");
 
-				h = zui_handle("tabobjects_7");
+				h = zui_handle(__ID__);
 				h.text = roundfp(rot.x) + "";
 				f = parse_float(zui_text_input(h, "X"));
 				let changed = false;
@@ -177,7 +184,7 @@ function tab_objects_draw(htab: zui_handle_t) {
 					rot.x = f;
 				}
 
-				h = zui_handle("tabobjects_8");
+				h = zui_handle(__ID__);
 				h.text = roundfp(rot.y) + "";
 				f = parse_float(zui_text_input(h, "Y"));
 				if (h.changed) {
@@ -185,7 +192,7 @@ function tab_objects_draw(htab: zui_handle_t) {
 					rot.y = f;
 				}
 
-				h = zui_handle("tabobjects_9");
+				h = zui_handle(__ID__);
 				h.text = roundfp(rot.z) + "";
 				f = parse_float(zui_text_input(h, "Z"));
 				if (h.changed) {
@@ -205,21 +212,21 @@ function tab_objects_draw(htab: zui_handle_t) {
 				zui_row([1 / 4, 1 / 4, 1 / 4, 1 / 4]);
 				zui_text("Scale");
 
-				h = zui_handle("tabobjects_10");
+				h = zui_handle(__ID__);
 				h.text = roundfp(scale.x) + "";
 				f = parse_float(zui_text_input(h, "X"));
 				if (h.changed) {
 					scale.x = f;
 				}
 
-				h = zui_handle("tabobjects_11");
+				h = zui_handle(__ID__);
 				h.text = roundfp(scale.y) + "";
 				f = parse_float(zui_text_input(h, "Y"));
 				if (h.changed) {
 					scale.y = f;
 				}
 
-				h = zui_handle("tabobjects_12");
+				h = zui_handle(__ID__);
 				h.text = roundfp(scale.z) + "";
 				f = parse_float(zui_text_input(h, "Z"));
 				if (h.changed) {
@@ -229,21 +236,21 @@ function tab_objects_draw(htab: zui_handle_t) {
 				zui_row([1 / 4, 1 / 4, 1 / 4, 1 / 4]);
 				zui_text("Dimensions");
 
-				h = zui_handle("tabobjects_13");
+				h = zui_handle(__ID__);
 				h.text = roundfp(dim.x) + "";
 				f = parse_float(zui_text_input(h, "X"));
 				if (h.changed) {
 					dim.x = f;
 				}
 
-				h = zui_handle("tabobjects_14");
+				h = zui_handle(__ID__);
 				h.text = roundfp(dim.y) + "";
 				f = parse_float(zui_text_input(h, "Y"));
 				if (h.changed) {
 					dim.y = f;
 				}
 
-				h = zui_handle("tabobjects_15");
+				h = zui_handle(__ID__);
 				h.text = roundfp(dim.z) + "";
 				f = parse_float(zui_text_input(h, "Z"));
 				if (h.changed) {
@@ -254,17 +261,17 @@ function tab_objects_draw(htab: zui_handle_t) {
 
 				if (context_context_raw.selected_object.name == "Scene") {
 					let p = scene_world;
-					p.strength = zui_slider(zui_handle("tabobjects_16", {value: p.strength}), "Environment", 0.0, 5.0, true);
+					p.strength = zui_slider(zui_handle(__ID__, {value: p.strength}), "Environment", 0.0, 5.0, true);
 				}
 				else if (context_context_raw.selected_object.ext_type == "light_object_t") {
 					let light = context_context_raw.selected_object.ext;
-					let light_handle = zui_handle("tabobjects_17");
+					let light_handle = zui_handle(__ID__);
 					light_handle.value = light.data.strength / 10;
 					light.data.strength = zui_slider(light_handle, "Strength", 0.0, 5.0, true) * 10;
 				}
 				else if (context_context_raw.selected_object.ext_type == "camera_object_t") {
 					let cam = context_context_raw.selected_object.ext;
-					let fov_handle = zui_handle("tabobjects_18");
+					let fov_handle = zui_handle(__ID__);
 					fov_handle.value = math_floor(cam.data.fov * 100) / 100;
 					cam.data.fov = zui_slider(fov_handle, "FoV", 0.3, 2.0, true);
 					if (fov_handle.changed) {

+ 1 - 1
armorlab/Sources/make_material.ts

@@ -71,7 +71,7 @@ function make_material_parse_paint_material() {
 			break;
 		}
 	}
-	for (let i: i32 = 0; i < m.contexts.length) {
+	for (let i: i32 = 0; i < m.contexts.length; ++i) {
 		let c = m.contexts[i];
 		if (c.name == "paint") {
 			array_remove(m.contexts, c);

+ 2 - 2
armorlab/Sources/nodes/inpaint_node.ts

@@ -51,8 +51,8 @@ function inpaint_node_init() {
 function inpaint_node_buttons(ui: zui_t, nodes: zui_nodes_t, node: zui_node_t) {
 	inpaint_node_auto = node.buttons[0].default_value == 0 ? false : true;
 	if (!inpaint_node_auto) {
-		inpaint_node_strength = zui_slider(zui_handle("inpaintnode_0", { value: inpaint_node_strength }), tr("strength"), 0, 1, true);
-		inpaint_node_prompt = zui_text_area(zui_handle("inpaintnode_1"), zui_align_t.LEFT, true, tr("prompt"), true);
+		inpaint_node_strength = zui_slider(zui_handle(__ID__, { value: inpaint_node_strength }), tr("strength"), 0, 1, true);
+		inpaint_node_prompt = zui_text_area(zui_handle(__ID__), zui_align_t.LEFT, true, tr("prompt"), true);
 		node.buttons[1].height = 1 + string_split(inpaint_node_prompt, "\n").length;
 	}
 	else {

+ 1 - 1
armorlab/Sources/nodes/text_to_photo_node.ts

@@ -31,7 +31,7 @@ function text_to_photo_node_get_cached_image(self: text_to_photo_node_t): image_
 
 function text_to_photo_node_buttons(ui: zui_t, nodes: zui_nodes_t, node: zui_node_t) {
 	text_to_photo_node_tiling = node.buttons[0].default_value == 0 ? false : true;
-	text_to_photo_node_prompt = zui_text_area(zui_handle("texttophotonode_0"), zui_align_t.LEFT, true, tr("prompt"), true);
+	text_to_photo_node_prompt = zui_text_area(zui_handle(__ID__), zui_align_t.LEFT, true, tr("prompt"), true);
 	node.buttons[1].height = string_split(text_to_photo_node_prompt, "\n").length;
 }
 

+ 2 - 2
armorlab/Sources/nodes/tiling_node.ts

@@ -27,8 +27,8 @@ function tiling_node_init() {
 function tiling_node_buttons(ui: zui_t, nodes: zui_nodes_t, node: zui_node_t) {
 	tiling_node_auto = node.buttons[0].default_value == 0 ? false : true;
 	if (!tiling_node_auto) {
-		tiling_node_strength = zui_slider(zui_handle("tilingnode_0", { value: tiling_node_strength }), tr("strength"), 0, 1, true);
-		tiling_node_prompt = zui_text_area(zui_handle("tilingnode_1"), zui_align_t.LEFT, true, tr("prompt"), true);
+		tiling_node_strength = zui_slider(zui_handle(__ID__, { value: tiling_node_strength }), tr("strength"), 0, 1, true);
+		tiling_node_prompt = zui_text_area(zui_handle(__ID__), zui_align_t.LEFT, true, tr("prompt"), true);
 		node.buttons[1].height = 1 + string_split(tiling_node_prompt, "\n").length;
 	}
 	else {

+ 1 - 1
armorlab/Sources/nodes/variance_node.ts

@@ -27,7 +27,7 @@ function variance_node_init() {
 }
 
 function variance_node_buttons(ui: zui_t, nodes: zui_nodes_t, node: zui_node_t) {
-	variance_node_prompt = zui_text_area(zui_handle("variancenode_0"), zui_align_t.LEFT, true, tr("prompt"), true);
+	variance_node_prompt = zui_text_area(zui_handle(__ID__), zui_align_t.LEFT, true, tr("prompt"), true);
 	node.buttons[0].height = string_split(variance_node_prompt, "\n").length;
 }
 

+ 10 - 14
armorpaint/Sources/nodes/brush_output_node.ts

@@ -25,19 +25,13 @@ function brush_output_node_parse_inputs(self: brush_output_node_t) {
 	let input4: any;
 	let input5: any;
 	let input6: any;
-	try {
-		logic_node_input_get(self.base.inputs[0], function (value: any) { input0 = value; });
-		logic_node_input_get(self.base.inputs[1], function (value: any) { input1 = value; });
-		logic_node_input_get(self.base.inputs[2], function (value: any) { input2 = value; });
-		logic_node_input_get(self.base.inputs[3], function (value: any) { input3 = value; });
-		logic_node_input_get(self.base.inputs[4], function (value: any) { input4 = value; });
-		logic_node_input_get(self.base.inputs[5], function (value: any) { input5 = value; });
-		logic_node_input_get(self.base.inputs[6], function (value: any) { input6 = value; });
-	}
-	catch (e: any) {
-		krom_log(e);
-		return;
-	}
+	logic_node_input_get(self.base.inputs[0], function (value: any) { input0 = value; });
+	logic_node_input_get(self.base.inputs[1], function (value: any) { input1 = value; });
+	logic_node_input_get(self.base.inputs[2], function (value: any) { input2 = value; });
+	logic_node_input_get(self.base.inputs[3], function (value: any) { input3 = value; });
+	logic_node_input_get(self.base.inputs[4], function (value: any) { input4 = value; });
+	logic_node_input_get(self.base.inputs[5], function (value: any) { input5 = value; });
+	logic_node_input_get(self.base.inputs[6], function (value: any) { input6 = value; });
 
 	context_raw.paint_vec = input0;
 	context_raw.brush_nodes_radius = input1;
@@ -45,7 +39,9 @@ function brush_output_node_parse_inputs(self: brush_output_node_t) {
 	context_raw.brush_nodes_angle = input3;
 
 	let opac: any = input4; // Float or texture name
-	if (opac == null) opac = 1.0;
+	if (opac == null) {
+		opac = 1.0;
+	}
 	if (typeof opac == "string") {
 		context_raw.brush_mask_image_is_alpha = ends_with(opac, ".a");
 		opac = substring(opac, 0, string_last_index_of(opac, "."));

+ 20 - 20
armorpaint/Sources/tab_layers.ts

@@ -181,7 +181,7 @@ function tab_layers_combo_filter() {
 			array_push(ar, a);
 		}
 	}
-	let filter_handle: zui_handle_t = zui_handle("tablayers_0");
+	let filter_handle: zui_handle_t = zui_handle(__ID__);
 	filter_handle.position = context_raw.layer_filter;
 	context_raw.layer_filter = zui_combo(filter_handle, ar, tr("Filter"), false, zui_align_t.LEFT);
 	if (filter_handle.changed) {
@@ -455,7 +455,7 @@ function tab_layers_draw_layer_slot_full(l: slot_layer_t, i: i32) {
 
 	if (has_panel) {
 		ui._y += center;
-		let layer_panel: zui_handle_t = zui_nest(zui_handle("tablayers_1"), l.id);
+		let layer_panel: zui_handle_t = zui_nest(zui_handle(__ID__), l.id);
 		layer_panel.selected = l.show_panel;
 		l.show_panel = zui_panel(layer_panel, "", true, false, false);
 		ui._y -= center;
@@ -497,7 +497,7 @@ function tab_layers_combo_object(ui: zui_t, l: slot_layer_t, label = false): zui
 			array_push(ar, a);
 		}
 	}
-	let object_handle: zui_handle_t = zui_nest(zui_handle("tablayers_2"), l.id);
+	let object_handle: zui_handle_t = zui_nest(zui_handle(__ID__), l.id);
 	object_handle.position = l.object_mask;
 	l.object_mask = zui_combo(object_handle, ar, tr("Object"), label, zui_align_t.LEFT);
 	if (object_handle.changed) {
@@ -519,7 +519,7 @@ function tab_layers_combo_object(ui: zui_t, l: slot_layer_t, label = false): zui
 }
 
 function tab_layers_combo_blending(ui: zui_t, l: slot_layer_t, label = false): zui_handle_t {
-	let blending_handle: zui_handle_t = zui_nest(zui_handle("tablayers_3"), l.id);
+	let blending_handle: zui_handle_t = zui_nest(zui_handle(__ID__), l.id);
 	blending_handle.position = l.blending;
 	zui_combo(blending_handle, [
 		tr("Mix"),
@@ -753,7 +753,7 @@ function tab_layers_draw_layer_context_menu(l: slot_layer_t, mini: bool) {
 	ui_menu_draw(function (ui: zui_t) {
 
 		if (mini) {
-			let visible_handle: zui_handle_t = zui_handle("tablayers_4");
+			let visible_handle: zui_handle_t = zui_handle(__ID__);
 			visible_handle.selected = l.visible;
 			ui_menu_fill(ui);
 			zui_check(visible_handle, tr("Visible"));
@@ -893,7 +893,7 @@ function tab_layers_draw_layer_context_menu(l: slot_layer_t, mini: bool) {
 
 		ui_menu_fill(ui);
 		ui_menu_align(ui);
-		let layer_opac_handle: zui_handle_t = zui_nest(zui_handle("tablayers_5"), l.id);
+		let layer_opac_handle: zui_handle_t = zui_nest(zui_handle(__ID__), l.id);
 		layer_opac_handle.value = l.mask_opacity;
 		zui_slider(layer_opac_handle, tr("Opacity"), 0.0, 1.0, true);
 		if (layer_opac_handle.changed) {
@@ -943,7 +943,7 @@ function tab_layers_draw_layer_context_menu(l: slot_layer_t, mini: bool) {
 		if (l.fill_layer != null) {
 			ui_menu_fill(ui);
 			ui_menu_align(ui);
-			let scale_handle: zui_handle_t = zui_nest(zui_handle("tablayers_6"), l.id);
+			let scale_handle: zui_handle_t = zui_nest(zui_handle(__ID__), l.id);
 			scale_handle.value = l.scale;
 			l.scale = zui_slider(scale_handle, tr("UV Scale"), 0.0, 5.0, true);
 			if (scale_handle.changed) {
@@ -958,7 +958,7 @@ function tab_layers_draw_layer_context_menu(l: slot_layer_t, mini: bool) {
 
 			ui_menu_fill(ui);
 			ui_menu_align(ui);
-			let angle_handle: zui_handle_t = zui_nest(zui_handle("tablayers_7"), l.id);
+			let angle_handle: zui_handle_t = zui_nest(zui_handle(__ID__), l.id);
 			angle_handle.value = l.angle;
 			l.angle = zui_slider(angle_handle, tr("Angle"), 0.0, 360, true, 1);
 			if (angle_handle.changed) {
@@ -974,7 +974,7 @@ function tab_layers_draw_layer_context_menu(l: slot_layer_t, mini: bool) {
 
 			ui_menu_fill(ui);
 			ui_menu_align(ui);
-			let uv_type_handle: zui_handle_t = zui_nest(zui_handle("tablayers_8"), l.id);
+			let uv_type_handle: zui_handle_t = zui_nest(zui_handle(__ID__), l.id);
 			uv_type_handle.position = l.uv_type;
 			l.uv_type = zui_inline_radio(uv_type_handle, [tr("UV Map"), tr("Triplanar"), tr("Project")], zui_align_t.LEFT);
 			if (uv_type_handle.changed) {
@@ -990,17 +990,17 @@ function tab_layers_draw_layer_context_menu(l: slot_layer_t, mini: bool) {
 		}
 
 		if (!slot_layer_is_group(l)) {
-			let base_handle: zui_handle_t = zui_nest(zui_handle("tablayers_9"), l.id);
-			let opac_handle: zui_handle_t = zui_nest(zui_handle("tablayers_10"), l.id);
-			let nor_handle: zui_handle_t = zui_nest(zui_handle("tablayers_11"), l.id);
-			let nor_blend_handle: zui_handle_t = zui_nest(zui_handle("tablayers_12"), l.id);
-			let occ_handle: zui_handle_t = zui_nest(zui_handle("tablayers_13"), l.id);
-			let rough_handle: zui_handle_t = zui_nest(zui_handle("tablayers_14"), l.id);
-			let met_handle: zui_handle_t = zui_nest(zui_handle("tablayers_15"), l.id);
-			let height_handle: zui_handle_t = zui_nest(zui_handle("tablayers_16"), l.id);
-			let height_blend_handle: zui_handle_t = zui_nest(zui_handle("tablayers_17"), l.id);
-			let emis_handle: zui_handle_t = zui_nest(zui_handle("tablayers_18"), l.id);
-			let subs_handle: zui_handle_t = zui_nest(zui_handle("tablayers_19"), l.id);
+			let base_handle: zui_handle_t = zui_nest(zui_handle(__ID__), l.id);
+			let opac_handle: zui_handle_t = zui_nest(zui_handle(__ID__), l.id);
+			let nor_handle: zui_handle_t = zui_nest(zui_handle(__ID__), l.id);
+			let nor_blend_handle: zui_handle_t = zui_nest(zui_handle(__ID__), l.id);
+			let occ_handle: zui_handle_t = zui_nest(zui_handle(__ID__), l.id);
+			let rough_handle: zui_handle_t = zui_nest(zui_handle(__ID__), l.id);
+			let met_handle: zui_handle_t = zui_nest(zui_handle(__ID__), l.id);
+			let height_handle: zui_handle_t = zui_nest(zui_handle(__ID__), l.id);
+			let height_blend_handle: zui_handle_t = zui_nest(zui_handle(__ID__), l.id);
+			let emis_handle: zui_handle_t = zui_nest(zui_handle(__ID__), l.id);
+			let subs_handle: zui_handle_t = zui_nest(zui_handle(__ID__), l.id);
 			base_handle.selected = l.paint_base;
 			opac_handle.selected = l.paint_opac;
 			nor_handle.selected = l.paint_nor;

+ 22 - 27
armorsculpt/Sources/import_mesh.ts

@@ -45,7 +45,7 @@ function import_mesh_finish_import() {
 
 	if (project_paint_objects.length > 1) {
 		// Sort by name
-		array_sort(project_paint_objects, function (a, b): i32 {
+		array_sort(project_paint_objects, function (a: string, b: string): i32 {
 			if (a.base.name < b.base.name) {
 				return -1;
 			}
@@ -158,39 +158,34 @@ function import_mesh_make_mesh(mesh: any, path: string) {
 }
 
 function import_mesh_add_mesh(mesh: any) {
+	let raw = import_mesh_raw_mesh(mesh);
+	if (mesh.cola != null) {
+		array_push(raw.vertex_arrays, { values: mesh.cola, attrib: "col", data: "short4norm" });
+	}
 
-	let _add_mesh = function () {
-		let raw = import_mesh_raw_mesh(mesh);
-		if (mesh.cola != null) {
-			array_push(raw.vertex_arrays, { values: mesh.cola, attrib: "col", data: "short4norm" });
-		}
-
-		let md: mesh_data_t = mesh_data_create(raw);
+	let md: mesh_data_t = mesh_data_create(raw);
 
-		let object = scene_add_mesh_object(md, context_raw.paint_object.materials, context_raw.paint_object.base);
-		object.base.name = mesh.base.name;
-		object.skip_context = "paint";
+	let object = scene_add_mesh_object(md, context_raw.paint_object.materials, context_raw.paint_object.base);
+	object.base.name = mesh.base.name;
+	object.skip_context = "paint";
 
-		// Ensure unique names
-		for (let i: i32 = 0; i < project_paint_objects.length; ++i) {
-			let p = project_paint_objects[i];
-			if (p.base.name == object.base.name) {
-				p.base.name += ".001";
-				p.data._.handle += ".001";
-				map_set(data_cached_meshes, p.data._.handle, p.data);
-			}
+	// Ensure unique names
+	for (let i: i32 = 0; i < project_paint_objects.length; ++i) {
+		let p = project_paint_objects[i];
+		if (p.base.name == object.base.name) {
+			p.base.name += ".001";
+			p.data._.handle += ".001";
+			map_set(data_cached_meshes, p.data._.handle, p.data);
 		}
+	}
 
-		array_push(project_paint_objects, object);
-
-		md._.handle = raw.name;
-		map_set(data_cached_meshes, md._.handle, md);
+	array_push(project_paint_objects, object);
 
-		context_raw.ddirty = 4;
-		ui_base_hwnds[tab_area_t.SIDEBAR0].redraws = 2;
-	}
+	md._.handle = raw.name;
+	map_set(data_cached_meshes, md._.handle, md);
 
-	_add_mesh();
+	context_raw.ddirty = 4;
+	ui_base_hwnds[tab_area_t.SIDEBAR0].redraws = 2;
 }
 
 function import_mesh_raw_mesh(mesh: any): mesh_data_t {

+ 5 - 10
armorsculpt/Sources/nodes/brush_output_node.ts

@@ -21,16 +21,11 @@ function brush_output_node_parse_inputs(self: brush_output_node_t) {
 	let input2: any;
 	let input3: any;
 	let input4: any;
-	try {
-		logic_node_input_get(self.base.inputs[0], function (value) { input0 = value; });
-		logic_node_input_get(self.base.inputs[1], function (value) { input1 = value; });
-		logic_node_input_get(self.base.inputs[2], function (value) { input2 = value; });
-		logic_node_input_get(self.base.inputs[3], function (value) { input3 = value; });
-		logic_node_input_get(self.base.inputs[4], function (value) { input4 = value; });
-	}
-	catch (_) {
-		return;
-	}
+	logic_node_input_get(self.base.inputs[0], function (value: any) { input0 = value; });
+	logic_node_input_get(self.base.inputs[1], function (value: any) { input1 = value; });
+	logic_node_input_get(self.base.inputs[2], function (value: any) { input2 = value; });
+	logic_node_input_get(self.base.inputs[3], function (value: any) { input3 = value; });
+	logic_node_input_get(self.base.inputs[4], function (value: any) { input4 = value; });
 
 	context_raw.paint_vec = input0;
 	context_raw.brush_nodes_radius = input1;

+ 3 - 3
armorsculpt/Sources/tab_layers.ts

@@ -85,7 +85,7 @@ function tab_layers_button_new(text: string) {
 function tab_layers_combo_filter() {
 	let ui = ui_base_ui;
 	let ar = [tr("All")];
-	let filter_handle = zui_handle("tablayers_0");
+	let filter_handle = zui_handle(__ID__);
 	filter_handle.position = context_raw.layer_filter;
 	context_raw.layer_filter = zui_combo(filter_handle, ar, tr("Filter"), false, zui_align_t.LEFT);
 }
@@ -318,7 +318,7 @@ function tab_layers_draw_layer_slot_full(l: slot_layer_t, i: i32) {
 
 	if (hasPanel) {
 		ui._y += center;
-		let layerPanel = zui_nest(zui_handle("tablayers_1"), l.id);
+		let layerPanel = zui_nest(zui_handle(__ID__), l.id);
 		layerPanel.selected = l.show_panel;
 		l.show_panel = zui_panel(layerPanel, "", true, false, false);
 		ui._y -= center;
@@ -352,7 +352,7 @@ function tab_layers_draw_layer_slot_full(l: slot_layer_t, i: i32) {
 
 function tab_layers_combo_object(ui: zui_t, l: slot_layer_t, label: bool = false): zui_handle_t {
 	let ar = [tr("Shared")];
-	let objectHandle = zui_nest(zui_handle("tablayers_2"), l.id);
+	let objectHandle = zui_nest(zui_handle(__ID__), l.id);
 	objectHandle.position = l.object_mask;
 	l.object_mask = zui_combo(objectHandle, ar, tr("Object"), label, zui_align_t.LEFT);
 	return objectHandle;

+ 1 - 0
base/Assets/themes/light.json

@@ -13,6 +13,7 @@
 	"SEPARATOR_COL": 4289967027,
 	"HIGHLIGHT_COL": 4284521948,
 	"CONTEXT_COL": 4284521948,
+	"PANEL_BG_COL": 4291611852,
 	"FONT_SIZE": 13,
 	"ELEMENT_W": 100,
 	"ELEMENT_H": 24,

+ 17 - 17
base/Sources/box_export.ts

@@ -98,20 +98,20 @@ function box_export_tab_export_textures(ui: zui_t, title: string, bake_material:
 
 		zui_row([0.5, 0.5]);
 		if (base_bits_handle.position == texture_bits_t.BITS8) {
-			context_raw.format_type = zui_combo(zui_handle("boxexport_0", { position: context_raw.format_type }), ["png", "jpg"], tr("Format"), true);
+			context_raw.format_type = zui_combo(zui_handle(__ID__, { position: context_raw.format_type }), ["png", "jpg"], tr("Format"), true);
 		}
 		else {
-			context_raw.format_type = zui_combo(zui_handle("boxexport_1", { position: context_raw.format_type }), ["exr"], tr("Format"), true);
+			context_raw.format_type = zui_combo(zui_handle(__ID__, { position: context_raw.format_type }), ["exr"], tr("Format"), true);
 		}
 
 		ui.enabled = context_raw.format_type == texture_ldr_format_t.JPG && base_bits_handle.position == texture_bits_t.BITS8;
-		context_raw.format_quality = zui_slider(zui_handle("boxexport_2", { value: context_raw.format_quality }), tr("Quality"), 0.0, 100.0, true, 1);
+		context_raw.format_quality = zui_slider(zui_handle(__ID__, { value: context_raw.format_quality }), tr("Quality"), 0.0, 100.0, true, 1);
 		ui.enabled = true;
 
 		///if is_paint
 		zui_row([0.5, 0.5]);
 		ui.enabled = !bake_material;
-		let layers_export_handle: zui_handle_t = zui_handle("boxexport_3");
+		let layers_export_handle: zui_handle_t = zui_handle(__ID__);
 		layers_export_handle.position = context_raw.layers_export;
 		context_raw.layers_export = zui_combo(layers_export_handle, [tr("Visible"), tr("Selected"), tr("Per Object"), tr("Per Udim Tile")], tr("Layers"), true);
 		ui.enabled = true;
@@ -120,7 +120,7 @@ function box_export_tab_export_textures(ui: zui_t, title: string, bake_material:
 		zui_combo(box_export_hpreset, box_export_files, tr("Preset"), true);
 		if (box_export_hpreset.changed) box_export_preset = null;
 
-		let layers_destination_handle: zui_handle_t = zui_handle("boxexport_4");
+		let layers_destination_handle: zui_handle_t = zui_handle(__ID__);
 		layers_destination_handle.position = context_raw.layers_destination;
 		context_raw.layers_destination = zui_combo(layers_destination_handle, [tr("Disk"), tr("Packed")], tr("Destination"), true);
 
@@ -189,9 +189,9 @@ function box_export_tab_presets(ui: zui_t) {
 		if (zui_button(tr("New"))) {
 			ui_box_show_custom(function (ui: zui_t) {
 				let tab_vertical: bool = config_raw.touch_ui;
-				if (zui_tab(zui_handle("boxexport_5"), tr("New Preset"), tab_vertical)) {
+				if (zui_tab(zui_handle(__ID__), tr("New Preset"), tab_vertical)) {
 					zui_row([0.5, 0.5]);
-					let preset_name: string = zui_text_input(zui_handle("boxexport_6", { text: "new_preset" }), tr("Name"));
+					let preset_name: string = zui_text_input(zui_handle(__ID__, { text: "new_preset" }), tr("Name"));
 					if (zui_button(tr("OK")) || ui.is_return_down) {
 						box_export_new_preset(preset_name);
 						box_export_fetch_presets();
@@ -317,7 +317,7 @@ function box_export_tab_atlases(ui: zui_t) {
 		for (let i: i32 = 0; i < project_paint_objects.length; ++i) {
 			zui_row([1 / 2, 1 / 2]);
 			zui_text(project_paint_objects[i].base.name);
-			let hatlas: zui_handle_t = zui_nest(zui_handle("boxexport_7"), i);
+			let hatlas: zui_handle_t = zui_nest(zui_handle(__ID__), i);
 			hatlas.position = project_atlas_objects[i];
 			project_atlas_objects[i] = zui_combo(hatlas, project_atlas_names, tr("Atlas"));
 		}
@@ -328,7 +328,7 @@ function box_export_tab_atlases(ui: zui_t) {
 function box_export_show_mesh() {
 	box_export_mesh_handle.position = context_raw.export_mesh_index;
 	ui_box_show_custom(function (ui: zui_t) {
-		let htab: zui_handle_t = zui_handle("boxexport_8");
+		let htab: zui_handle_t = zui_handle(__ID__);
 		box_export_tab_export_mesh(ui, htab);
 	});
 }
@@ -339,7 +339,7 @@ function box_export_tab_export_mesh(ui: zui_t, htab: zui_handle_t) {
 
 		zui_row([1 / 2, 1 / 2]);
 
-		context_raw.export_mesh_format = zui_combo(zui_handle("boxexport_9", { position: context_raw.export_mesh_format }), ["obj", "arm"], tr("Format"), true);
+		context_raw.export_mesh_format = zui_combo(zui_handle(__ID__, { position: context_raw.export_mesh_format }), ["obj", "arm"], tr("Format"), true);
 
 		let ar: string[] = [tr("All")];
 		for (let i: i32 = 0; i < project_paint_objects.length; ++i) {
@@ -348,7 +348,7 @@ function box_export_tab_export_mesh(ui: zui_t, htab: zui_handle_t) {
 		}
 		zui_combo(box_export_mesh_handle, ar, tr("Meshes"), true);
 
-		let apply_displacement: bool = zui_check(zui_handle("boxexport_10"), tr("Apply Displacement"));
+		let apply_displacement: bool = zui_check(zui_handle(__ID__), tr("Apply Displacement"));
 
 		let tris: i32 = 0;
 		let pos: i32 = box_export_mesh_handle.position;
@@ -394,11 +394,11 @@ function box_export_tab_export_mesh(ui: zui_t, htab: zui_handle_t) {
 ///if (is_paint || is_sculpt)
 function box_export_show_material() {
 	ui_box_show_custom(function (ui: zui_t) {
-		let htab: zui_handle_t = zui_handle("boxexport_11");
+		let htab: zui_handle_t = zui_handle(__ID__);
 		let tab_vertical: bool = config_raw.touch_ui;
 		if (zui_tab(htab, tr("Export Material"), tab_vertical)) {
-			let h1: zui_handle_t = zui_handle("boxexport_12");
-			let h2: zui_handle_t = zui_handle("boxexport_13");
+			let h1: zui_handle_t = zui_handle(__ID__);
+			let h2: zui_handle_t = zui_handle(__ID__);
 			h1.selected = context_raw.pack_assets_on_export;
 			h2.selected = context_raw.write_icon_on_export;
 			context_raw.pack_assets_on_export = zui_check(h1, tr("Pack Assets"));
@@ -425,11 +425,11 @@ function box_export_show_material() {
 
 function box_export_show_brush() {
 	ui_box_show_custom(function (ui: zui_t) {
-		let htab: zui_handle_t = zui_handle("boxexport_14");
+		let htab: zui_handle_t = zui_handle(__ID__);
 		let tab_vertical: bool = config_raw.touch_ui;
 		if (zui_tab(htab, tr("Export Brush"), tab_vertical)) {
-			let h1: zui_handle_t = zui_handle("boxexport_15");
-			let h2: zui_handle_t = zui_handle("boxexport_16");
+			let h1: zui_handle_t = zui_handle(__ID__);
+			let h2: zui_handle_t = zui_handle(__ID__);
 			h1.selected = context_raw.pack_assets_on_export;
 			h2.selected = context_raw.write_icon_on_export;
 			context_raw.pack_assets_on_export = zui_check(h1, tr("Pack Assets"));

+ 63 - 65
base/Sources/box_preferences.ts

@@ -16,7 +16,7 @@ function box_preferences_show() {
 				box_preferences_locales = translator_get_supported_locales();
 			}
 
-			let locale_handle: zui_handle_t = zui_handle("boxpreferences_0", { position: array_index_of(box_preferences_locales, config_raw.locale) });
+			let locale_handle: zui_handle_t = zui_handle(__ID__, { position: array_index_of(box_preferences_locales, config_raw.locale) });
 			zui_combo(locale_handle, box_preferences_locales, tr("Language"), true);
 			if (locale_handle.changed) {
 				let locale_code: string = box_preferences_locales[locale_handle.position];
@@ -25,11 +25,13 @@ function box_preferences_show() {
 				ui_base_tag_ui_redraw();
 			}
 
-			let hscale: zui_handle_t = zui_handle("boxpreferences_1", { value: config_raw.window_scale });
+			let hscale: zui_handle_t = zui_handle(__ID__, { value: config_raw.window_scale });
 			zui_slider(hscale, tr("UI Scale"), 1.0, 4.0, true, 10);
 			if (context_raw.hscale_was_changed && !ui.input_down) {
 				context_raw.hscale_was_changed = false;
-				if (hscale.value == null || isNaN(hscale.value)) hscale.value = 1.0;
+				if (hscale.value == null) {
+					hscale.value = 1.0;
+				}
 				config_raw.window_scale = hscale.value;
 				box_preferences_set_scale();
 			}
@@ -37,37 +39,37 @@ function box_preferences_show() {
 				context_raw.hscale_was_changed = true;
 			}
 
-			let hspeed: zui_handle_t = zui_handle("boxpreferences_2", { value: config_raw.camera_zoom_speed });
+			let hspeed: zui_handle_t = zui_handle(__ID__, { value: config_raw.camera_zoom_speed });
 			config_raw.camera_zoom_speed = zui_slider(hspeed, tr("Camera Zoom Speed"), 0.1, 4.0, true);
 
-			hspeed = zui_handle("boxpreferences_3", { value: config_raw.camera_rotation_speed });
+			hspeed = zui_handle(__ID__, { value: config_raw.camera_rotation_speed });
 			config_raw.camera_rotation_speed = zui_slider(hspeed, tr("Camera Rotation Speed"), 0.1, 4.0, true);
 
-			hspeed = zui_handle("boxpreferences_4", { value: config_raw.camera_pan_speed });
+			hspeed = zui_handle(__ID__, { value: config_raw.camera_pan_speed });
 			config_raw.camera_pan_speed = zui_slider(hspeed, tr("Camera Pan Speed"), 0.1, 4.0, true);
 
-			let zoom_direction_handle: zui_handle_t = zui_handle("boxpreferences_5", { position: config_raw.zoom_direction });
+			let zoom_direction_handle: zui_handle_t = zui_handle(__ID__, { position: config_raw.zoom_direction });
 			zui_combo(zoom_direction_handle, [tr("Vertical"), tr("Vertical Inverted"), tr("Horizontal"), tr("Horizontal Inverted"), tr("Vertical and Horizontal"), tr("Vertical and Horizontal Inverted")], tr("Direction to Zoom"), true);
 			if (zoom_direction_handle.changed) {
 				config_raw.zoom_direction = zoom_direction_handle.position;
 			}
 
-			config_raw.wrap_mouse = zui_check(zui_handle("boxpreferences_6", { selected: config_raw.wrap_mouse }), tr("Wrap Mouse"));
+			config_raw.wrap_mouse = zui_check(zui_handle(__ID__, { selected: config_raw.wrap_mouse }), tr("Wrap Mouse"));
 			if (ui.is_hovered) {
 				zui_tooltip(tr("Wrap mouse around view boundaries during camera control"));
 			}
 
-			config_raw.node_preview = zui_check(zui_handle("boxpreferences_7", { selected: config_raw.node_preview }), tr("Show Node Preview"));
+			config_raw.node_preview = zui_check(zui_handle(__ID__, { selected: config_raw.node_preview }), tr("Show Node Preview"));
 
 			ui.changed = false;
-			config_raw.show_asset_names = zui_check(zui_handle("boxpreferences_8", { selected: config_raw.show_asset_names }), tr("Show Asset Names"));
+			config_raw.show_asset_names = zui_check(zui_handle(__ID__, { selected: config_raw.show_asset_names }), tr("Show Asset Names"));
 			if (ui.changed) {
 				ui_base_tag_ui_redraw();
 			}
 
 			///if !(krom_android || krom_ios)
 			ui.changed = false;
-			config_raw.touch_ui = zui_check(zui_handle("boxpreferences_9", { selected: config_raw.touch_ui }), tr("Touch UI"));
+			config_raw.touch_ui = zui_check(zui_handle(__ID__, { selected: config_raw.touch_ui }), tr("Touch UI"));
 			if (ui.changed) {
 				zui_set_touch_scroll(config_raw.touch_ui);
 				zui_set_touch_hold(config_raw.touch_ui);
@@ -78,7 +80,7 @@ function box_preferences_show() {
 			}
 			///end
 
-			config_raw.splash_screen = zui_check(zui_handle("boxpreferences_10", { selected: config_raw.splash_screen }), tr("Splash Screen"));
+			config_raw.splash_screen = zui_check(zui_handle(__ID__, { selected: config_raw.splash_screen }), tr("Splash Screen"));
 
 			// Zui.text("Node Editor");
 			// let grid_snap: bool = Zui.check(Zui.handle("boxpreferences_11", { selected: false }), "Grid Snap");
@@ -134,7 +136,7 @@ function box_preferences_show() {
 			if (box_preferences_themes == null) {
 				box_preferences_fetch_themes();
 			}
-			box_preferences_theme_handle = zui_handle("boxpreferences_12", { position: box_preferences_get_theme_index() });
+			box_preferences_theme_handle = zui_handle(__ID__, { position: box_preferences_get_theme_index() });
 
 			zui_begin_sticky();
 			zui_row([1 / 4, 1 / 4, 1 / 4, 1 / 4]);
@@ -147,9 +149,9 @@ function box_preferences_show() {
 
 			if (zui_button(tr("New"))) {
 				ui_box_show_custom(function (ui: zui_t) {
-					if (zui_tab(zui_handle("boxpreferences_13"), tr("New Theme"))) {
+					if (zui_tab(zui_handle(__ID__), tr("New Theme"))) {
 						zui_row([0.5, 0.5]);
-						let theme_name: string = zui_text_input(zui_handle("boxpreferences_14", { text: "new_theme" }), tr("Name"));
+						let theme_name: string = zui_text_input(zui_handle(__ID__, { text: "new_theme" }), tr("Name"));
 						if (zui_button(tr("OK")) || ui.is_return_down) {
 							let template: string = json_stringify(base_theme);
 							if (!ends_with(theme_name, ".json")) {
@@ -188,7 +190,7 @@ function box_preferences_show() {
 
 			let i: i32 = 0;
 			let theme: any = base_theme;
-			let hlist: zui_handle_t = zui_handle("boxpreferences_15");
+			let hlist: zui_handle_t = zui_handle(__ID__);
 
 			// Viewport color
 			let h: zui_handle_t = zui_nest(hlist, i++, { color: box_preferences_world_color });
@@ -207,7 +209,7 @@ function box_preferences_show() {
 			if (val < 0) {
 				val += 4294967296;
 			}
-			h.text = val.toString(16);
+			h.text = i32_to_string_hex(val);
 			zui_text_input(h, "VIEWPORT_COL");
 			h.color = parse_int_hex(h.text);
 
@@ -226,14 +228,10 @@ function box_preferences_show() {
 			}
 
 			// Theme fields
-			let props: string[] = Object.getOwnPropertyNames(theme_t.prototype);
-			for (let i: i32 = 0; i < props.length; ++i) {
-				let key: string = props[i];
-				if (key == "constructor") {
-					continue;
-				}
+			for (let i: i32 = 0; i < zui_theme_keys.length; ++i) {
+				let key: string = zui_theme_keys[i];
 
-				let h: zui_handle_t = zui_nest(hlist, i++);
+				let h: zui_handle_t = zui_nest(hlist, i);
 				let val: any = theme[key];
 
 				let is_hex: bool = ends_with(key, "_COL");
@@ -271,7 +269,7 @@ function box_preferences_show() {
 					theme[key] = i;
 				}
 				else {
-					h.text = is_hex ? val.toString(16) : val.toString();
+					h.text = is_hex ? i32_to_string_hex(val) : i32_to_string(val);
 					zui_text_input(h, key);
 					if (is_hex) {
 						theme[key] = parse_int_hex(h.text);
@@ -291,7 +289,7 @@ function box_preferences_show() {
 		}
 
 		if (zui_tab(box_preferences_htab, tr("Usage"), true)) {
-			context_raw.undo_handle = zui_handle("boxpreferences_16", { value: config_raw.undo_steps });
+			context_raw.undo_handle = zui_handle(__ID__, { value: config_raw.undo_steps });
 			config_raw.undo_steps = math_floor(zui_slider(context_raw.undo_handle, tr("Undo Steps"), 1, 64, false, 1));
 			if (config_raw.undo_steps < 1) {
 				config_raw.undo_steps = math_floor(context_raw.undo_handle.value = 1);
@@ -316,12 +314,12 @@ function box_preferences_show() {
 			}
 
 			///if is_paint
-			config_raw.dilate_radius = math_floor(zui_slider(zui_handle("boxpreferences_17", { value: config_raw.dilate_radius }), tr("Dilate Radius"), 0.0, 16.0, true, 1));
+			config_raw.dilate_radius = math_floor(zui_slider(zui_handle(__ID__, { value: config_raw.dilate_radius }), tr("Dilate Radius"), 0.0, 16.0, true, 1));
 			if (ui.is_hovered) {
 				zui_tooltip(tr("Dilate painted textures to prevent seams"));
 			}
 
-			let dilate_handle: zui_handle_t = zui_handle("boxpreferences_18", { position: config_raw.dilate });
+			let dilate_handle: zui_handle_t = zui_handle(__ID__, { position: config_raw.dilate });
 			zui_combo(dilate_handle, [tr("Instant"), tr("Delayed")], tr("Dilate"), true);
 			if (dilate_handle.changed) {
 				config_raw.dilate = dilate_handle.position;
@@ -329,20 +327,20 @@ function box_preferences_show() {
 			///end
 
 			///if is_lab
-			let workspace_handle: zui_handle_t = zui_handle("boxpreferences_19", { position: config_raw.workspace });
+			let workspace_handle: zui_handle_t = zui_handle(__ID__, { position: config_raw.workspace });
 			zui_combo(workspace_handle, [tr("3D View"), tr("2D View")], tr("Default Workspace"), true);
 			if (workspace_handle.changed) {
 				config_raw.workspace = workspace_handle.position;
 			}
 			///end
 
-			let camera_controls_handle: zui_handle_t = zui_handle("boxpreferences_20", { position: config_raw.camera_controls });
+			let camera_controls_handle: zui_handle_t = zui_handle(__ID__, { position: config_raw.camera_controls });
 			zui_combo(camera_controls_handle, [tr("Orbit"), tr("Rotate"), tr("Fly")], tr("Default Camera Controls"), true);
 			if (camera_controls_handle.changed) {
 				config_raw.camera_controls = camera_controls_handle.position;
 			}
 
-			let layer_res_handle: zui_handle_t = zui_handle("boxpreferences_21", { position: config_raw.layer_res });
+			let layer_res_handle: zui_handle_t = zui_handle(__ID__, { position: config_raw.layer_res });
 
 			///if is_paint
 			///if (krom_android || krom_ios)
@@ -364,17 +362,17 @@ function box_preferences_show() {
 				config_raw.layer_res = layer_res_handle.position;
 			}
 
-			let server_handle: zui_handle_t = zui_handle("boxpreferences_22", { text: config_raw.server });
+			let server_handle: zui_handle_t = zui_handle(__ID__, { text: config_raw.server });
 			config_raw.server = zui_text_input(server_handle, tr("Cloud Server"));
 
 			///if (is_paint || is_sculpt)
-			let material_live_handle: zui_handle_t = zui_handle("boxpreferences_23", {selected: config_raw.material_live });
+			let material_live_handle: zui_handle_t = zui_handle(__ID__, {selected: config_raw.material_live });
 			config_raw.material_live = zui_check(material_live_handle, tr("Live Material Preview"));
 			if (ui.is_hovered) {
 				zui_tooltip(tr("Instantly update material preview on node change"));
 			}
 
-			let brush_live_handle: zui_handle_t = zui_handle("boxpreferences_24", { selected: config_raw.brush_live });
+			let brush_live_handle: zui_handle_t = zui_handle(__ID__, { selected: config_raw.brush_live });
 			config_raw.brush_live = zui_check(brush_live_handle, tr("Live Brush Preview"));
 			if (ui.is_hovered) {
 				zui_tooltip(tr("Draw live brush preview in viewport"));
@@ -383,14 +381,14 @@ function box_preferences_show() {
 				context_raw.ddirty = 2;
 			}
 
-			let brush_3d_handle: zui_handle_t = zui_handle("boxpreferences_25", { selected: config_raw.brush_3d });
+			let brush_3d_handle: zui_handle_t = zui_handle(__ID__, { selected: config_raw.brush_3d });
 			config_raw.brush_3d = zui_check(brush_3d_handle, tr("3D Cursor"));
 			if (brush_3d_handle.changed) {
 				make_material_parse_paint_material();
 			}
 
 			ui.enabled = config_raw.brush_3d;
-			let brush_depth_reject_handle: zui_handle_t = zui_handle("boxpreferences_26", { selected: config_raw.brush_depth_reject });
+			let brush_depth_reject_handle: zui_handle_t = zui_handle(__ID__, { selected: config_raw.brush_depth_reject });
 			config_raw.brush_depth_reject = zui_check(brush_depth_reject_handle, tr("Depth Reject"));
 			if (brush_depth_reject_handle.changed) {
 				make_material_parse_paint_material();
@@ -398,14 +396,14 @@ function box_preferences_show() {
 
 			zui_row([0.5, 0.5]);
 
-			let brush_angle_reject_handle: zui_handle_t = zui_handle("boxpreferences_27", { selected: config_raw.brush_angle_reject });
+			let brush_angle_reject_handle: zui_handle_t = zui_handle(__ID__, { selected: config_raw.brush_angle_reject });
 			config_raw.brush_angle_reject = zui_check(brush_angle_reject_handle, tr("Angle Reject"));
 			if (brush_angle_reject_handle.changed) {
 				make_material_parse_paint_material();
 			}
 
 			if (!config_raw.brush_angle_reject) ui.enabled = false;
-			let angle_dot_handle: zui_handle_t = zui_handle("boxpreferences_28", { value: context_raw.brush_angle_reject_dot });
+			let angle_dot_handle: zui_handle_t = zui_handle(__ID__, { value: context_raw.brush_angle_reject_dot });
 			context_raw.brush_angle_reject_dot = zui_slider(angle_dot_handle, tr("Angle"), 0.0, 1.0, true);
 			if (angle_dot_handle.changed) {
 				make_material_parse_paint_material();
@@ -414,7 +412,7 @@ function box_preferences_show() {
 			///end
 
 			///if is_lab
-			config_raw.gpu_inference = zui_check(zui_handle("boxpreferences_29", { selected: config_raw.gpu_inference }), tr("Use GPU"));
+			config_raw.gpu_inference = zui_check(zui_handle(__ID__, { selected: config_raw.gpu_inference }), tr("Use GPU"));
 			if (ui.is_hovered) {
 				zui_tooltip(tr("Use GPU to accelerate node graph processing"));
 			}
@@ -430,12 +428,12 @@ function box_preferences_show() {
 
 		if (zui_tab(box_preferences_htab, pen_name, true)) {
 			zui_text(tr("Pressure controls"));
-			config_raw.pressure_radius = zui_check(zui_handle("boxpreferences_30", { selected: config_raw.pressure_radius }), tr("Brush Radius"));
-			config_raw.pressure_sensitivity = zui_slider(zui_handle("boxpreferences_31", { value: config_raw.pressure_sensitivity }), tr("Sensitivity"), 0.0, 10.0, true);
+			config_raw.pressure_radius = zui_check(zui_handle(__ID__, { selected: config_raw.pressure_radius }), tr("Brush Radius"));
+			config_raw.pressure_sensitivity = zui_slider(zui_handle(__ID__, { value: config_raw.pressure_sensitivity }), tr("Sensitivity"), 0.0, 10.0, true);
 			///if (is_paint || is_sculpt)
-			config_raw.pressure_hardness = zui_check(zui_handle("boxpreferences_32", { selected: config_raw.pressure_hardness }), tr("Brush Hardness"));
-			config_raw.pressure_opacity = zui_check(zui_handle("boxpreferences_33", { selected: config_raw.pressure_opacity }), tr("Brush Opacity"));
-			config_raw.pressure_angle = zui_check(zui_handle("boxpreferences_34", { selected: config_raw.pressure_angle }), tr("Brush Angle"));
+			config_raw.pressure_hardness = zui_check(zui_handle(__ID__, { selected: config_raw.pressure_hardness }), tr("Brush Hardness"));
+			config_raw.pressure_opacity = zui_check(zui_handle(__ID__, { selected: config_raw.pressure_opacity }), tr("Brush Opacity"));
+			config_raw.pressure_angle = zui_check(zui_handle(__ID__, { selected: config_raw.pressure_angle }), tr("Brush Angle"));
 			///end
 
 			zui_end_element();
@@ -450,15 +448,15 @@ function box_preferences_show() {
 			}
 		}
 
-		context_raw.hssao = zui_handle("boxpreferences_35", { selected: config_raw.rp_ssao });
-		context_raw.hssr = zui_handle("boxpreferences_36", { selected: config_raw.rp_ssr });
-		context_raw.hbloom = zui_handle("boxpreferences_37", { selected: config_raw.rp_bloom });
-		context_raw.hsupersample = zui_handle("boxpreferences_38", { position: config_get_super_sample_quality(config_raw.rp_supersample) });
-		context_raw.hvxao = zui_handle("boxpreferences_39", { selected: config_raw.rp_gi });
+		context_raw.hssao = zui_handle(__ID__, { selected: config_raw.rp_ssao });
+		context_raw.hssr = zui_handle(__ID__, { selected: config_raw.rp_ssr });
+		context_raw.hbloom = zui_handle(__ID__, { selected: config_raw.rp_bloom });
+		context_raw.hsupersample = zui_handle(__ID__, { position: config_get_super_sample_quality(config_raw.rp_supersample) });
+		context_raw.hvxao = zui_handle(__ID__, { selected: config_raw.rp_gi });
 		if (zui_tab(box_preferences_htab, tr("Viewport"), true)) {
 			///if (krom_direct3d12 || krom_vulkan || krom_metal)
 
-			let hpathtrace_mode: zui_handle_t = zui_handle("boxpreferences_40", { position: context_raw.pathtrace_mode });
+			let hpathtrace_mode: zui_handle_t = zui_handle(__ID__, { position: context_raw.pathtrace_mode });
 			context_raw.pathtrace_mode = zui_combo(hpathtrace_mode, [tr("Core"), tr("Full")], tr("Path Tracer"), true);
 			if (hpathtrace_mode.changed) {
 				render_path_raytrace_ready = false;
@@ -466,7 +464,7 @@ function box_preferences_show() {
 
 			///end
 
-			let hrender_mode: zui_handle_t = zui_handle("boxpreferences_41", { position: context_raw.render_mode });
+			let hrender_mode: zui_handle_t = zui_handle(__ID__, { position: context_raw.render_mode });
 			context_raw.render_mode = zui_combo(hrender_mode, [tr("Full"), tr("Mobile")], tr("Renderer"), true);
 			if (hrender_mode.changed) {
 				context_set_render_path();
@@ -488,12 +486,12 @@ function box_preferences_show() {
 				}
 
 				ui.enabled = context_raw.hvxao.selected;
-				let h: zui_handle_t = zui_handle("boxpreferences_42", { value: context_raw.vxao_offset });
+				let h: zui_handle_t = zui_handle(__ID__, { value: context_raw.vxao_offset });
 				context_raw.vxao_offset = zui_slider(h, tr("Cone Offset"), 1.0, 4.0, true);
 				if (h.changed) {
 					context_raw.ddirty = 2;
 				}
-				h = zui_handle("boxpreferences_43", { value: context_raw.vxao_aperture });
+				h = zui_handle(__ID__, { value: context_raw.vxao_aperture });
 				context_raw.vxao_aperture = zui_slider(h, tr("Aperture"), 1.0, 4.0, true);
 				if (h.changed) {
 					context_raw.ddirty = 2;
@@ -515,13 +513,13 @@ function box_preferences_show() {
 				}
 			}
 
-			let h: zui_handle_t = zui_handle("boxpreferences_44", { value: config_raw.rp_vignette });
+			let h: zui_handle_t = zui_handle(__ID__, { value: config_raw.rp_vignette });
 			config_raw.rp_vignette = zui_slider(h, tr("Vignette"), 0.0, 1.0, true);
 			if (h.changed) {
 				context_raw.ddirty = 2;
 			}
 
-			h = zui_handle("boxpreferences_45", { value: config_raw.rp_grain });
+			h = zui_handle(__ID__, { value: config_raw.rp_grain });
 			config_raw.rp_grain = zui_slider(h, tr("Noise Grain"), 0.0, 1.0, true);
 			if (h.changed) {
 				context_raw.ddirty = 2;
@@ -533,8 +531,8 @@ function box_preferences_show() {
 
 			let cam: camera_object_t = scene_camera;
 			let cam_raw: camera_data_t = cam.data;
-			let near_handle: zui_handle_t = zui_handle("boxpreferences_47");
-			let far_handle: zui_handle_t = zui_handle("boxpreferences_48");
+			let near_handle: zui_handle_t = zui_handle(__ID__);
+			let far_handle: zui_handle_t = zui_handle(__ID__);
 			near_handle.value = math_floor(cam_raw.near_plane * 1000) / 1000;
 			far_handle.value = math_floor(cam_raw.far_plane * 100) / 100;
 			cam_raw.near_plane = zui_slider(near_handle, tr("Clip Start"), 0.001, 1.0, true);
@@ -543,7 +541,7 @@ function box_preferences_show() {
 				camera_object_build_proj(cam);
 			}
 
-			let disp_handle: zui_handle_t = zui_handle("boxpreferences_49", { value: config_raw.displace_strength });
+			let disp_handle: zui_handle_t = zui_handle(__ID__, { value: config_raw.displace_strength });
 			config_raw.displace_strength = zui_slider(disp_handle, tr("Displacement Strength"), 0.0, 10.0, true);
 			if (disp_handle.changed) {
 				context_raw.ddirty = 2;
@@ -559,7 +557,7 @@ function box_preferences_show() {
 			zui_begin_sticky();
 			zui_row([1 / 4, 1 / 4, 1 / 4, 1 / 4]);
 
-			box_preferences_preset_handle = zui_handle("boxpreferences_50", { position: box_preferences_get_preset_index() });
+			box_preferences_preset_handle = zui_handle(__ID__, { position: box_preferences_get_preset_index() });
 			zui_combo(box_preferences_preset_handle, box_preferences_files_keymap, tr("Preset"));
 			if (box_preferences_preset_handle.changed) {
 				config_raw.keymap = box_preferences_files_keymap[box_preferences_preset_handle.position] + ".json";
@@ -569,9 +567,9 @@ function box_preferences_show() {
 
 			if (zui_button(tr("New"))) {
 				ui_box_show_custom(function (ui: zui_t) {
-					if (zui_tab(zui_handle("boxpreferences_51"), tr("New Keymap"))) {
+					if (zui_tab(zui_handle(__ID__), tr("New Keymap"))) {
 						zui_row([0.5, 0.5]);
-						let keymap_name: string = zui_text_input(zui_handle("boxpreferences_52", { text: "new_keymap" }), tr("Name"));
+						let keymap_name: string = zui_text_input(zui_handle(__ID__, { text: "new_keymap" }), tr("Name"));
 						if (zui_button(tr("OK")) || ui.is_return_down) {
 							let template: string = json_stringify(base_default_keymap);
 							if (!ends_with(keymap_name, ".json")) {
@@ -613,7 +611,7 @@ function box_preferences_show() {
 			ui.changed = false;
 			for (let i: i32 = 0; i < base_keymap_keys.length; ++i) {
 				let key: string = base_keymap_keys[i];
-				let h: zui_handle_t = zui_nest(zui_handle("boxpreferences_53"), index++);
+				let h: zui_handle_t = zui_nest(zui_handle(__ID__), index++);
 				h.text = config_keymap[key];
 				let text: string = zui_text_input(h, key, zui_align_t.LEFT);
 				config_keymap[key] = text;
@@ -628,9 +626,9 @@ function box_preferences_show() {
 			zui_row([1 / 4, 1 / 4]);
 			if (zui_button(tr("New"))) {
 				ui_box_show_custom(function (ui: zui_t) {
-					if (zui_tab(zui_handle("boxpreferences_54"), tr("New Plugin"))) {
+					if (zui_tab(zui_handle(__ID__), tr("New Plugin"))) {
 						zui_row([0.5, 0.5]);
-						let plugin_name: string = zui_text_input(zui_handle("boxpreferences_55", { text: "new_plugin" }), tr("Name"));
+						let plugin_name: string = zui_text_input(zui_handle(__ID__, { text: "new_plugin" }), tr("Name"));
 						if (zui_button(tr("OK")) || ui.is_return_down) {
 							let template: string =
 "let plugin = create();\
@@ -670,7 +668,7 @@ plugin.draw_ui = function (ui) {\
 			if (config_raw.plugins == null) {
 				config_raw.plugins = [];
 			}
-			let h: zui_handle_t = zui_handle("boxpreferences_56", { selected: false });
+			let h: zui_handle_t = zui_handle(__ID__, { selected: false });
 			for (let i: i32 = 0; i < box_preferences_files_plugin.length; ++i) {
 				let f: string = box_preferences_files_plugin[i];
 				let is_js: bool = ends_with(f, ".js");

+ 111 - 49
base/Sources/config.ts

@@ -318,26 +318,26 @@ type config_t = {
 	// "system" is a special case that will use the system locale
 	locale?: string;
 	// Window
-	window_mode?: Null<i32>; // window, fullscreen
-	window_w?: Null<i32>;
-	window_h?: Null<i32>;
-	window_x?: Null<i32>;
-	window_y?: Null<i32>;
-	window_resizable?: Null<bool>;
-	window_maximizable?: Null<bool>;
-	window_minimizable?: Null<bool>;
-	window_vsync?: Null<bool>;
-	window_frequency?: Null<i32>;
-	window_scale?: Null<f32>;
+	window_mode?: i32; // window, fullscreen
+	window_w?: i32;
+	window_h?: i32;
+	window_x?: i32;
+	window_y?: i32;
+	window_resizable?: bool;
+	window_maximizable?: bool;
+	window_minimizable?: bool;
+	window_vsync?: bool;
+	window_frequency?: i32;
+	window_scale?: f32;
 	// Render path
-	rp_supersample?: Null<f32>;
-	rp_ssao?: Null<bool>;
-	rp_ssr?: Null<bool>;
-	rp_bloom?: Null<bool>;
-	rp_motionblur?: Null<bool>;
-	rp_gi?: Null<bool>;
-	rp_vignette?: Null<f32>;
-	rp_grain?: Null<f32>;
+	rp_supersample?: f32;
+	rp_ssao?: bool;
+	rp_ssr?: bool;
+	rp_bloom?: bool;
+	rp_motionblur?: bool;
+	rp_gi?: bool;
+	rp_vignette?: f32;
+	rp_grain?: f32;
 	// Application
 	version?: string;
 	sha?: string; // Commit id
@@ -346,38 +346,100 @@ type config_t = {
 	plugins?: string[]; // List of enabled plugins
 	keymap?: string; // Link to keymap file
 	theme?: string; // Link to theme file
-	undo_steps?: Null<i32>; // Number of undo steps to preserve
-	camera_pan_speed?: Null<f32>;
-	camera_zoom_speed?: Null<f32>;
-	camera_rotation_speed?: Null<f32>;
-	zoom_direction?: Null<i32>;
-	wrap_mouse?: Null<bool>;
-	show_asset_names?: Null<bool>;
-	touch_ui?: Null<bool>;
-	splash_screen?: Null<bool>;
+	undo_steps?: i32; // Number of undo steps to preserve
+	camera_pan_speed?: f32;
+	camera_zoom_speed?: f32;
+	camera_rotation_speed?: f32;
+	zoom_direction?: i32;
+	wrap_mouse?: bool;
+	show_asset_names?: bool;
+	touch_ui?: bool;
+	splash_screen?: bool;
 	layout?: i32[]; // Sizes
 	layout_tabs?: i32[]; // Active tabs
-	workspace?: Null<i32>;
-	camera_controls?: Null<i32>; // Orbit, rotate
+	workspace?: i32;
+	camera_controls?: i32; // Orbit, rotate
 	server?: string;
 
-	pressure_radius?: Null<bool>; // Pen pressure controls
-	pressure_sensitivity?: Null<f32>;
-	displace_strength?: Null<f32>;
-	layer_res?: Null<i32>;
-	brush_live?: Null<bool>;
-	brush_3d?: Null<bool>;
-	node_preview?: Null<bool>;
-
-	pressure_hardness?: Null<bool>;
-	pressure_angle?: Null<bool>;
-	pressure_opacity?: Null<bool>;
-	material_live?: Null<bool>;
-	brush_depth_reject?: Null<bool>;
-	brush_angle_reject?: Null<bool>;
-
-	dilate?: Null<i32>;
-	dilate_radius?: Null<i32>;
-
-	gpu_inference?: Null<bool>;
+	pressure_radius?: bool; // Pen pressure controls
+	pressure_sensitivity?: f32;
+	displace_strength?: f32;
+	layer_res?: i32;
+	brush_live?: bool;
+	brush_3d?: bool;
+	node_preview?: bool;
+
+	pressure_hardness?: bool;
+	pressure_angle?: bool;
+	pressure_opacity?: bool;
+	material_live?: bool;
+	brush_depth_reject?: bool;
+	brush_angle_reject?: bool;
+
+	dilate?: i32;
+	dilate_radius?: i32;
+
+	///if is_lab
+	gpu_inference?: bool;
+	///end
 };
+
+// let config_keys: string[] = [
+// 	"locale",
+// 	"window_mode",
+// 	"window_w",
+// 	"window_h",
+// 	"window_x",
+// 	"window_y",
+// 	"window_resizable",
+// 	"window_maximizable",
+// 	"window_minimizable",
+// 	"window_vsync",
+// 	"window_frequency",
+// 	"window_scale",
+// 	"rp_supersample",
+// 	"rp_ssao",
+// 	"rp_ssr",
+// 	"rp_bloom",
+// 	"rp_motionblur",
+// 	"rp_gi",
+// 	"rp_vignette",
+// 	"rp_grain",
+// 	"version",
+// 	"sha",
+// 	"recent_projects",
+// 	"bookmarks",
+// 	"plugins",
+// 	"keymap",
+// 	"theme",
+// 	"undo_steps",
+// 	"camera_pan_speed",
+// 	"camera_zoom_speed",
+// 	"camera_rotation_speed",
+// 	"zoom_direction",
+// 	"wrap_mouse",
+// 	"show_asset_names",
+// 	"touch_ui",
+// 	"splash_screen",
+// 	"layout",
+// 	"layout_tabs",
+// 	"workspace",
+// 	"camera_controls",
+// 	"server",
+// 	"pressure_radius",
+// 	"pressure_sensitivity",
+// 	"displace_strength",
+// 	"layer_res",
+// 	"brush_live",
+// 	"brush_3d",
+// 	"node_preview",
+// 	"pressure_hardness",
+// 	"pressure_angle",
+// 	"pressure_opacity",
+// 	"material_live",
+// 	"brush_depth_reject",
+// 	"brush_angle_reject",
+// 	"dilate",
+// 	"dilate_radius",
+// 	"gpu_inference",
+// ];

+ 3 - 3
base/Sources/history.ts

@@ -442,10 +442,10 @@ function history_reset() {
 }
 
 ///if (is_paint || is_sculpt)
-function history_edit_nodes(canvas: zui_node_canvas_t, canvas_type: i32, canvas_group: Null<i32> = null) {
+function history_edit_nodes(canvas: zui_node_canvas_t, canvas_type: i32, canvas_group: i32 = -1) {
 ///end
 ///if is_lab
-function history_edit_nodes(canvas: zui_node_canvas_t, canvas_group: Null<i32> = null) {
+function history_edit_nodes(canvas: zui_node_canvas_t, canvas_group: i32 = -1) {
 ///end
 	let step: step_t = history_push(tr("Edit Nodes"));
 	step.canvas_group = canvas_group;
@@ -702,7 +702,7 @@ function history_copy_to_undo(from_id: i32, to_id: i32, is_mask: bool) {
 
 function history_get_canvas_owner(step: step_t): any {
 	///if (is_paint || is_sculpt)
-	return step.canvas_group == null ?
+	return step.canvas_group == -1 ?
 		project_materials[step.material] :
 		project_material_groups[step.canvas_group];
 	///end

+ 1 - 1
base/Sources/nodes/separate_vector_node.ts

@@ -38,7 +38,7 @@ let separate_vector_node_def: zui_node_t = {
 			name: _tr("Vector"),
 			type: "VECTOR",
 			color: 0xff6363c7,
-			default_value: new f32_array_t([0.0, 0.0, 0.0])
+			default_value: f32_array_create_xyz(0.0, 0.0, 0.0)
 		}
 	],
 	outputs: [

+ 3 - 3
base/Sources/nodes/vector_math_node.ts

@@ -154,7 +154,7 @@ let vector_math_node_def: zui_node_t = {
 			name: _tr("Vector"),
 			type: "VECTOR",
 			color: 0xff6363c7,
-			default_value: new f32_array_t([0.0, 0.0, 0.0])
+			default_value: f32_array_create_xyz(0.0, 0.0, 0.0)
 		},
 		{
 			id: 0,
@@ -162,7 +162,7 @@ let vector_math_node_def: zui_node_t = {
 			name: _tr("Vector"),
 			type: "VECTOR",
 			color: 0xff6363c7,
-			default_value: new f32_array_t([0.0, 0.0, 0.0])
+			default_value: f32_array_create_xyz(0.0, 0.0, 0.0)
 		}
 	],
 	outputs: [
@@ -172,7 +172,7 @@ let vector_math_node_def: zui_node_t = {
 			name: _tr("Vector"),
 			type: "VECTOR",
 			color: 0xff6363c7,
-			default_value: new f32_array_t([0.0, 0.0, 0.0])
+			default_value: f32_array_create_xyz(0.0, 0.0, 0.0)
 		},
 		{
 			id: 0,

+ 1 - 1
base/Sources/nodes/vector_node.ts

@@ -101,7 +101,7 @@ let vector_node_def: zui_node_t = {
 			name: _tr("Vector"),
 			type: "VECTOR",
 			color: 0xff6363c7,
-			default_value: new f32_array_t([0.0, 0.0, 0.0])
+			default_value: f32_array_create_xyz(0.0, 0.0, 0.0)
 		}
 	],
 	buttons: []

+ 106 - 106
base/Sources/nodes_material.ts

@@ -25,7 +25,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Color"),
 					type: "RGBA",
 					color: 0xffc7c729,
-					default_value: new f32_array_t([0.8, 0.8, 0.8, 1.0])
+					default_value: f32_array_create_xyzw(0.8, 0.8, 0.8, 1.0)
 				},
 				{
 					id: 0,
@@ -33,7 +33,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Vector"),
 					type: "VECTOR",
 					color: 0xff6363c7,
-					default_value: new f32_array_t([0.0, 0.0, 0.0])
+					default_value: f32_array_create_xyz(0.0, 0.0, 0.0)
 				},
 				{
 					id: 0,
@@ -66,7 +66,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("View Vector"),
 					type: "VECTOR",
 					color: 0xff6363c7,
-					default_value: new f32_array_t([0.0, 0.0, 0.0])
+					default_value: f32_array_create_xyz(0.0, 0.0, 0.0)
 				},
 				{
 					id: 0,
@@ -111,7 +111,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Normal"),
 					type: "VECTOR",
 					color: 0xff6363c7,
-					default_value: new f32_array_t([0.0, 0.0, 0.0])
+					default_value: f32_array_create_xyz(0.0, 0.0, 0.0)
 				}
 			],
 			outputs: [
@@ -141,7 +141,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Position"),
 					type: "VECTOR",
 					color: 0xff6363c7,
-					default_value: new f32_array_t([0.0, 0.0, 0.0])
+					default_value: f32_array_create_xyz(0.0, 0.0, 0.0)
 				},
 				{
 					id: 0,
@@ -149,7 +149,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Normal"),
 					type: "VECTOR",
 					color: 0xff6363c7,
-					default_value: new f32_array_t([0.0, 0.0, 0.0])
+					default_value: f32_array_create_xyz(0.0, 0.0, 0.0)
 				},
 				{
 					id: 0,
@@ -157,7 +157,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Tangent"),
 					type: "VECTOR",
 					color: 0xff6363c7,
-					default_value: new f32_array_t([0.0, 0.0, 0.0])
+					default_value: f32_array_create_xyz(0.0, 0.0, 0.0)
 				},
 				{
 					id: 0,
@@ -165,7 +165,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("True Normal"),
 					type: "VECTOR",
 					color: 0xff6363c7,
-					default_value: new f32_array_t([0.0, 0.0, 0.0])
+					default_value: f32_array_create_xyz(0.0, 0.0, 0.0)
 				},
 				{
 					id: 0,
@@ -173,7 +173,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Incoming"),
 					type: "VECTOR",
 					color: 0xff6363c7,
-					default_value: new f32_array_t([0.0, 0.0, 0.0])
+					default_value: f32_array_create_xyz(0.0, 0.0, 0.0)
 				},
 				{
 					id: 0,
@@ -181,7 +181,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Parametric"),
 					type: "VECTOR",
 					color: 0xff6363c7,
-					default_value: new f32_array_t([0.0, 0.0, 0.0])
+					default_value: f32_array_create_xyz(0.0, 0.0, 0.0)
 				},
 				{
 					id: 0,
@@ -225,7 +225,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Base Color"),
 					type: "RGBA",
 					color: 0xffc7c729,
-					default_value: new f32_array_t([0.0, 0.0, 0.0, 1.0])
+					default_value: f32_array_create_xyzw(0.0, 0.0, 0.0, 1.0)
 				},
 				{
 					id: 0,
@@ -265,7 +265,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Normal Map"),
 					type: "VECTOR",
 					color: -10238109,
-					default_value: new f32_array_t([0.5, 0.5, 1.0])
+					default_value: f32_array_create_xyz(0.5, 0.5, 1.0)
 				},
 				{
 					id: 0,
@@ -350,7 +350,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Normal"),
 					type: "VECTOR",
 					color: 0xff6363c7,
-					default_value: new f32_array_t([0.0, 0.0, 0.0])
+					default_value: f32_array_create_xyz(0.0, 0.0, 0.0)
 				}
 			],
 			outputs: [
@@ -388,7 +388,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Base Color"),
 					type: "RGBA",
 					color: 0xffc7c729,
-					default_value: new f32_array_t([0.0, 0.0, 0.0, 1.0])
+					default_value: f32_array_create_xyzw(0.0, 0.0, 0.0, 1.0)
 				},
 				{
 					id: 0,
@@ -428,7 +428,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Normal Map"),
 					type: "VECTOR",
 					color: -10238109,
-					default_value: new f32_array_t([0.5, 0.5, 1.0])
+					default_value: f32_array_create_xyz(0.5, 0.5, 1.0)
 				},
 				{
 					id: 0,
@@ -479,7 +479,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Location"),
 					type: "VECTOR",
 					color: 0xff6363c7,
-					default_value: new f32_array_t([0.0, 0.0, 0.0])
+					default_value: f32_array_create_xyz(0.0, 0.0, 0.0)
 				},
 				{
 					id: 0,
@@ -487,7 +487,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Color"),
 					type: "RGBA",
 					color: 0xffc7c729,
-					default_value: new f32_array_t([0.0, 0.0, 0.0, 1.0])
+					default_value: f32_array_create_xyzw(0.0, 0.0, 0.0, 1.0)
 				},
 				{
 					id: 0,
@@ -531,7 +531,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Base Color"),
 					type: "RGBA",
 					color: 0xffc7c729,
-					default_value: new f32_array_t([0.0, 0.0, 0.0, 1.0])
+					default_value: f32_array_create_xyzw(0.0, 0.0, 0.0, 1.0)
 				},
 				{
 					id: 0,
@@ -571,7 +571,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Normal Map"),
 					type: "VECTOR",
 					color: -10238109,
-					default_value: new f32_array_t([0.5, 0.5, 1.0])
+					default_value: f32_array_create_xyz(0.5, 0.5, 1.0)
 				},
 				{
 					id: 0,
@@ -615,7 +615,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Color"),
 					type: "RGBA",
 					color: 0xffc7c729,
-					default_value: new f32_array_t([0.5, 0.5, 0.5, 1.0])
+					default_value: f32_array_create_xyzw(0.5, 0.5, 0.5, 1.0)
 				}
 			],
 			buttons: [
@@ -693,7 +693,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Tangent"),
 					type: "VECTOR",
 					color: 0xff6363c7,
-					default_value: new f32_array_t([0.0, 0.0, 0.0])
+					default_value: f32_array_create_xyz(0.0, 0.0, 0.0)
 				}
 			],
 			buttons: []
@@ -713,7 +713,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Generated"),
 					type: "VECTOR",
 					color: 0xff6363c7,
-					default_value: new f32_array_t([0.0, 0.0, 0.0])
+					default_value: f32_array_create_xyz(0.0, 0.0, 0.0)
 				},
 				{
 					id: 0,
@@ -721,7 +721,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Normal"),
 					type: "VECTOR",
 					color: 0xff6363c7,
-					default_value: new f32_array_t([0.0, 0.0, 0.0])
+					default_value: f32_array_create_xyz(0.0, 0.0, 0.0)
 				},
 				{
 					id: 0,
@@ -729,7 +729,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("UV"),
 					type: "VECTOR",
 					color: 0xff6363c7,
-					default_value: new f32_array_t([0.0, 0.0, 0.0])
+					default_value: f32_array_create_xyz(0.0, 0.0, 0.0)
 				},
 				{
 					id: 0,
@@ -737,7 +737,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Object"),
 					type: "VECTOR",
 					color: 0xff6363c7,
-					default_value: new f32_array_t([0.0, 0.0, 0.0])
+					default_value: f32_array_create_xyz(0.0, 0.0, 0.0)
 				},
 				{
 					id: 0,
@@ -745,7 +745,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Camera"),
 					type: "VECTOR",
 					color: 0xff6363c7,
-					default_value: new f32_array_t([0.0, 0.0, 0.0])
+					default_value: f32_array_create_xyz(0.0, 0.0, 0.0)
 				},
 				{
 					id: 0,
@@ -753,7 +753,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Window"),
 					type: "VECTOR",
 					color: 0xff6363c7,
-					default_value: new f32_array_t([0.0, 0.0, 0.0])
+					default_value: f32_array_create_xyz(0.0, 0.0, 0.0)
 				},
 				{
 					id: 0,
@@ -761,7 +761,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Reflection"),
 					type: "VECTOR",
 					color: 0xff6363c7,
-					default_value: new f32_array_t([0.0, 0.0, 0.0])
+					default_value: f32_array_create_xyz(0.0, 0.0, 0.0)
 				}
 			],
 			buttons: []
@@ -781,7 +781,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("UV"),
 					type: "VECTOR",
 					color: 0xff6363c7,
-					default_value: new f32_array_t([0.0, 0.0, 0.0])
+					default_value: f32_array_create_xyz(0.0, 0.0, 0.0)
 				}
 			],
 			buttons: []
@@ -829,7 +829,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Color"),
 					type: "RGBA",
 					color: 0xffc7c729,
-					default_value: new f32_array_t([0.8, 0.8, 0.8, 1.0])
+					default_value: f32_array_create_xyzw(0.8, 0.8, 0.8, 1.0)
 				},
 				{
 					id: 0,
@@ -895,7 +895,7 @@ let nodes_material_list: zui_node_t[][] = [
 	// 				name: _tr("Base Color"),
 	// 				type: "RGBA",
 	// 				color: 0xffc7c729,
-	// 				default_value: new f32_array_t([0.8, 0.8, 0.8, 1.0])
+	// 				default_value: f32_array_create_xyzw(0.8, 0.8, 0.8, 1.0)
 	// 			},
 	// 			{
 	// 				id: 0,
@@ -935,7 +935,7 @@ let nodes_material_list: zui_node_t[][] = [
 	// 				name: _tr("Normal Map"),
 	// 				type: "VECTOR",
 	// 				color: -10238109,
-	// 				default_value: new f32_array_t([0.5, 0.5, 1.0])
+	// 				default_value: f32_array_create_xyz(0.5, 0.5, 1.0)
 	// 			},
 	// 			{
 	// 				id: 0,
@@ -981,7 +981,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Vector"),
 					type: "VECTOR",
 					color: 0xff6363c7,
-					default_value: new f32_array_t([0.0, 0.0, 0.0])
+					default_value: f32_array_create_xyz(0.0, 0.0, 0.0)
 				},
 				{
 					id: 0,
@@ -989,7 +989,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Color 1"),
 					type: "RGBA",
 					color: 0xffc7c729,
-					default_value: new f32_array_t([0.8, 0.8, 0.8])
+					default_value: f32_array_create_xyz(0.8, 0.8, 0.8)
 				},
 				{
 					id: 0,
@@ -997,7 +997,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Color 2"),
 					type: "RGBA",
 					color: 0xffc7c729,
-					default_value: new f32_array_t([0.2, 0.2, 0.2])
+					default_value: f32_array_create_xyz(0.2, 0.2, 0.2)
 				},
 				{
 					id: 0,
@@ -1005,7 +1005,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Mortar"),
 					type: "RGBA",
 					color: 0xffc7c729,
-					default_value: new f32_array_t([0.0, 0.0, 0.0])
+					default_value: f32_array_create_xyz(0.0, 0.0, 0.0)
 				},
 				{
 					id: 0,
@@ -1025,7 +1025,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Color"),
 					type: "RGBA",
 					color: 0xffc7c729,
-					default_value: new f32_array_t([0.8, 0.8, 0.8, 1.0])
+					default_value: f32_array_create_xyzw(0.8, 0.8, 0.8, 1.0)
 				},
 				{
 					id: 0,
@@ -1052,7 +1052,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Vector"),
 					type: "VECTOR",
 					color: 0xff6363c7,
-					default_value: new f32_array_t([0.0, 0.0, 0.0])
+					default_value: f32_array_create_xyz(0.0, 0.0, 0.0)
 				},
 				{
 					id: 0,
@@ -1060,7 +1060,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Color 1"),
 					type: "RGBA",
 					color: 0xffc7c729,
-					default_value: new f32_array_t([0.8, 0.8, 0.8])
+					default_value: f32_array_create_xyz(0.8, 0.8, 0.8)
 				},
 				{
 					id: 0,
@@ -1068,7 +1068,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Color 2"),
 					type: "RGBA",
 					color: 0xffc7c729,
-					default_value: new f32_array_t([0.2, 0.2, 0.2])
+					default_value: f32_array_create_xyz(0.2, 0.2, 0.2)
 				},
 				{
 					id: 0,
@@ -1088,7 +1088,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Color"),
 					type: "RGBA",
 					color: 0xffc7c729,
-					default_value: new f32_array_t([0.8, 0.8, 0.8, 1.0])
+					default_value: f32_array_create_xyzw(0.8, 0.8, 0.8, 1.0)
 				},
 				{
 					id: 0,
@@ -1166,7 +1166,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Vector"),
 					type: "VECTOR",
 					color: 0xff6363c7,
-					default_value: new f32_array_t([0.0, 0.0, 0.0])
+					default_value: f32_array_create_xyz(0.0, 0.0, 0.0)
 				}
 			],
 			outputs: [
@@ -1176,7 +1176,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Color"),
 					type: "RGBA",
 					color: 0xffc7c729,
-					default_value: new f32_array_t([0.8, 0.8, 0.8, 1.0])
+					default_value: f32_array_create_xyzw(0.8, 0.8, 0.8, 1.0)
 				},
 				{
 					id: 0,
@@ -1212,7 +1212,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Vector"),
 					type: "VECTOR",
 					color: 0xff6363c7,
-					default_value: new f32_array_t([0.0, 0.0, 0.0])
+					default_value: f32_array_create_xyz(0.0, 0.0, 0.0)
 				}
 			],
 			outputs: [
@@ -1222,7 +1222,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Color"),
 					type: "RGBA",
 					color: 0xffc7c729,
-					default_value: new f32_array_t([0.0, 0.0, 0.0, 1.0])
+					default_value: f32_array_create_xyzw(0.0, 0.0, 0.0, 1.0)
 				},
 				{
 					id: 0,
@@ -1262,7 +1262,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Vector"),
 					type: "VECTOR",
 					color: 0xff6363c7,
-					default_value: new f32_array_t([0.0, 0.0, 0.0])
+					default_value: f32_array_create_xyz(0.0, 0.0, 0.0)
 				},
 				{
 					id: 0,
@@ -1282,7 +1282,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Color"),
 					type: "RGBA",
 					color: 0xffc7c729,
-					default_value: new f32_array_t([0.8, 0.8, 0.8, 1.0])
+					default_value: f32_array_create_xyzw(0.8, 0.8, 0.8, 1.0)
 				},
 				{
 					id: 0,
@@ -1309,7 +1309,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Vector"),
 					type: "VECTOR",
 					color: 0xff6363c7,
-					default_value: new f32_array_t([0.0, 0.0, 0.0])
+					default_value: f32_array_create_xyz(0.0, 0.0, 0.0)
 				},
 				{
 					id: 0,
@@ -1348,7 +1348,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Vector"),
 					type: "VECTOR",
 					color: 0xff6363c7,
-					default_value: new f32_array_t([0.0, 0.0, 0.0])
+					default_value: f32_array_create_xyz(0.0, 0.0, 0.0)
 				},
 				{
 					id: 0,
@@ -1368,7 +1368,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Color"),
 					type: "RGBA",
 					color: 0xffc7c729,
-					default_value: new f32_array_t([0.8, 0.8, 0.8, 1.0])
+					default_value: f32_array_create_xyzw(0.8, 0.8, 0.8, 1.0)
 				},
 				{
 					id: 0,
@@ -1395,7 +1395,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Vector"),
 					type: "VECTOR",
 					color: 0xff6363c7,
-					default_value: new f32_array_t([0.0, 0.0, 0.0])
+					default_value: f32_array_create_xyz(0.0, 0.0, 0.0)
 				},
 				{
 					id: 0,
@@ -1415,7 +1415,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Color"),
 					type: "RGBA",
 					color: 0xffc7c729,
-					default_value: new f32_array_t([0.8, 0.8, 0.8, 1.0])
+					default_value: f32_array_create_xyzw(0.8, 0.8, 0.8, 1.0)
 				},
 				{
 					id: 0,
@@ -1450,7 +1450,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Vector"),
 					type: "VECTOR",
 					color: 0xff6363c7,
-					default_value: new f32_array_t([0.0, 0.0, 0.0])
+					default_value: f32_array_create_xyz(0.0, 0.0, 0.0)
 				},
 				{
 					id: 0,
@@ -1470,7 +1470,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Color"),
 					type: "RGBA",
 					color: 0xffc7c729,
-					default_value: new f32_array_t([0.8, 0.8, 0.8, 1.0])
+					default_value: f32_array_create_xyzw(0.8, 0.8, 0.8, 1.0)
 				},
 				{
 					id: 0,
@@ -1499,7 +1499,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Color"),
 					type: "RGBA",
 					color: 0xffc7c729,
-					default_value: new f32_array_t([0.8, 0.8, 0.8, 1.0])
+					default_value: f32_array_create_xyzw(0.8, 0.8, 0.8, 1.0)
 				},
 				{
 					id: 0,
@@ -1517,7 +1517,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Color"),
 					type: "RGBA",
 					color: 0xffc7c729,
-					default_value: new f32_array_t([0.8, 0.8, 0.8, 1.0])
+					default_value: f32_array_create_xyzw(0.8, 0.8, 0.8, 1.0)
 				}
 			],
 			buttons: []
@@ -1536,7 +1536,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Color"),
 					type: "RGBA",
 					color: 0xffc7c729,
-					default_value: new f32_array_t([0.8, 0.8, 0.8, 1.0])
+					default_value: f32_array_create_xyzw(0.8, 0.8, 0.8, 1.0)
 				},
 				{
 					id: 0,
@@ -1562,7 +1562,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Color"),
 					type: "RGBA",
 					color: 0xffc7c729,
-					default_value: new f32_array_t([0.8, 0.8, 0.8, 1.0])
+					default_value: f32_array_create_xyzw(0.8, 0.8, 0.8, 1.0)
 				}
 			],
 			buttons: []
@@ -1581,7 +1581,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Color"),
 					type: "RGBA",
 					color: 0xffc7c729,
-					default_value: new f32_array_t([0.8, 0.8, 0.8, 1.0])
+					default_value: f32_array_create_xyzw(0.8, 0.8, 0.8, 1.0)
 				},
 				{
 					id: 0,
@@ -1599,7 +1599,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Color"),
 					type: "RGBA",
 					color: 0xffc7c729,
-					default_value: new f32_array_t([0.8, 0.8, 0.8, 1.0])
+					default_value: f32_array_create_xyzw(0.8, 0.8, 0.8, 1.0)
 				}
 			],
 			buttons: []
@@ -1650,7 +1650,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Color"),
 					type: "RGBA",
 					color: 0xffc7c729,
-					default_value: new f32_array_t([0.8, 0.8, 0.8, 1.0])
+					default_value: f32_array_create_xyzw(0.8, 0.8, 0.8, 1.0)
 				}
 			],
 			outputs: [
@@ -1660,7 +1660,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Color"),
 					type: "RGBA",
 					color: 0xffc7c729,
-					default_value: new f32_array_t([0.8, 0.8, 0.8, 1.0])
+					default_value: f32_array_create_xyzw(0.8, 0.8, 0.8, 1.0)
 				}
 			],
 			buttons: []
@@ -1687,7 +1687,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Color"),
 					type: "RGBA",
 					color: 0xffc7c729,
-					default_value: new f32_array_t([0.0, 0.0, 0.0, 1.0])
+					default_value: f32_array_create_xyzw(0.0, 0.0, 0.0, 1.0)
 				}
 			],
 			outputs: [
@@ -1697,7 +1697,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Color"),
 					type: "RGBA",
 					color: 0xffc7c729,
-					default_value: new f32_array_t([0.8, 0.8, 0.8, 1.0])
+					default_value: f32_array_create_xyzw(0.8, 0.8, 0.8, 1.0)
 				}
 			],
 			buttons: []
@@ -1724,7 +1724,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Color 1"),
 					type: "RGBA",
 					color: 0xffc7c729,
-					default_value: new f32_array_t([0.5, 0.5, 0.5, 1.0])
+					default_value: f32_array_create_xyzw(0.5, 0.5, 0.5, 1.0)
 				},
 				{
 					id: 0,
@@ -1732,7 +1732,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Color 2"),
 					type: "RGBA",
 					color: 0xffc7c729,
-					default_value: new f32_array_t([0.5, 0.5, 0.5, 1.0])
+					default_value: f32_array_create_xyzw(0.5, 0.5, 0.5, 1.0)
 				}
 			],
 			outputs: [
@@ -1742,7 +1742,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Color"),
 					type: "RGBA",
 					color: 0xffc7c729,
-					default_value: new f32_array_t([0.8, 0.8, 0.8, 1.0])
+					default_value: f32_array_create_xyzw(0.8, 0.8, 0.8, 1.0)
 				}
 			],
 			buttons: [
@@ -1785,7 +1785,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Color"),
 					type: "RGBA",
 					color: 0xffc7c729,
-					default_value: new f32_array_t([0.0, 0.0, 0.0, 1.0])
+					default_value: f32_array_create_xyzw(0.0, 0.0, 0.0, 1.0)
 				}
 			],
 			outputs: [
@@ -1795,7 +1795,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Color"),
 					type: "RGBA",
 					color: 0xffc7c729,
-					default_value: new f32_array_t([0.8, 0.8, 0.8, 1.0])
+					default_value: f32_array_create_xyzw(0.8, 0.8, 0.8, 1.0)
 				}
 			],
 			buttons: []
@@ -1814,7 +1814,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Color"),
 					type: "RGBA",
 					color: 0xffc7c729,
-					default_value: new f32_array_t([0.8, 0.8, 0.8, 1.0])
+					default_value: f32_array_create_xyzw(0.8, 0.8, 0.8, 1.0)
 				},
 				{
 					id: 0,
@@ -1844,7 +1844,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Color"),
 					type: "RGBA",
 					color: 0xffc7c729,
-					default_value: new f32_array_t([0.8, 0.8, 0.8, 1.0])
+					default_value: f32_array_create_xyzw(0.8, 0.8, 0.8, 1.0)
 				}
 			],
 			buttons: []
@@ -1889,7 +1889,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Normal"),
 					type: "VECTOR",
 					color: 0xff6363c7,
-					default_value: new f32_array_t([0.0, 0.0, 0.0])
+					default_value: f32_array_create_xyz(0.0, 0.0, 0.0)
 				}
 			],
 			outputs: [
@@ -1899,7 +1899,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Normal Map"),
 					type: "VECTOR",
 					color: -10238109,
-					default_value: new f32_array_t([0.0, 0.0, 0.0])
+					default_value: f32_array_create_xyz(0.0, 0.0, 0.0)
 				}
 			],
 			buttons: []
@@ -1918,7 +1918,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Vector"),
 					type: "VECTOR",
 					color: 0xff6363c7,
-					default_value: new f32_array_t([0.0, 0.0, 0.0])
+					default_value: f32_array_create_xyz(0.0, 0.0, 0.0)
 				},
 				{
 					id: 0,
@@ -1926,7 +1926,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Location"),
 					type: "VECTOR",
 					color: 0xff6363c7,
-					default_value: new f32_array_t([0.0, 0.0, 0.0]),
+					default_value: f32_array_create_xyz(0.0, 0.0, 0.0),
 					display: 1
 				},
 				{
@@ -1935,7 +1935,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Rotation"),
 					type: "VECTOR",
 					color: 0xff6363c7,
-					default_value: new f32_array_t([0.0, 0.0, 0.0]),
+					default_value: f32_array_create_xyz(0.0, 0.0, 0.0),
 					max: 360.0,
 					display: 1
 				},
@@ -1945,7 +1945,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Scale"),
 					type: "VECTOR",
 					color: 0xff6363c7,
-					default_value: new f32_array_t([1.0, 1.0, 1.0]),
+					default_value: f32_array_create_xyz(1.0, 1.0, 1.0),
 					display: 1
 				}
 			],
@@ -1956,7 +1956,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Vector"),
 					type: "VECTOR",
 					color: 0xff6363c7,
-					default_value: new f32_array_t([0.0, 0.0, 0.0])
+					default_value: f32_array_create_xyz(0.0, 0.0, 0.0)
 				}
 			],
 			buttons: []
@@ -1975,7 +1975,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Normal Map 1"),
 					type: "VECTOR",
 					color: -10238109,
-					default_value: new f32_array_t([0.5, 0.5, 1.0])
+					default_value: f32_array_create_xyz(0.5, 0.5, 1.0)
 				},
 				{
 					id: 0,
@@ -1983,7 +1983,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Normal Map 2"),
 					type: "VECTOR",
 					color: -10238109,
-					default_value: new f32_array_t([0.5, 0.5, 1.0])
+					default_value: f32_array_create_xyz(0.5, 0.5, 1.0)
 				}
 			],
 			outputs: [
@@ -1993,7 +1993,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Normal Map"),
 					type: "VECTOR",
 					color: -10238109,
-					default_value: new f32_array_t([0.5, 0.5, 1.0])
+					default_value: f32_array_create_xyz(0.5, 0.5, 1.0)
 				}
 			],
 			buttons: [
@@ -2020,7 +2020,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Normal"),
 					type: "VECTOR",
 					color: 0xff6363c7,
-					default_value: new f32_array_t([0.0, 0.0, 0.0])
+					default_value: f32_array_create_xyz(0.0, 0.0, 0.0)
 				}
 			],
 			outputs: [
@@ -2030,7 +2030,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Normal"),
 					type: "VECTOR",
 					color: 0xff6363c7,
-					default_value: new f32_array_t([0.0, 0.0, 0.0])
+					default_value: f32_array_create_xyz(0.0, 0.0, 0.0)
 				},
 				{
 					id: 0,
@@ -2045,7 +2045,7 @@ let nodes_material_list: zui_node_t[][] = [
 				{
 					name: _tr("Vector"),
 					type: "VECTOR",
-					default_value: new f32_array_t([0.0, 0.0, 0.0]),
+					default_value: f32_array_create_xyz(0.0, 0.0, 0.0),
 					output: 0
 				}
 			]
@@ -2074,7 +2074,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Normal Map"),
 					type: "VECTOR",
 					color: -10238109,
-					default_value: new f32_array_t([0.5, 0.5, 1.0])
+					default_value: f32_array_create_xyz(0.5, 0.5, 1.0)
 				}
 			],
 			outputs: [
@@ -2084,7 +2084,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Normal Map"),
 					type: "VECTOR",
 					color: -10238109,
-					default_value: new f32_array_t([0.5, 0.5, 1.0])
+					default_value: f32_array_create_xyz(0.5, 0.5, 1.0)
 				}
 			],
 			buttons: []
@@ -2111,7 +2111,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Vector"),
 					type: "VECTOR",
 					color: 0xff6363c7,
-					default_value: new f32_array_t([0.0, 0.0, 0.0])
+					default_value: f32_array_create_xyz(0.0, 0.0, 0.0)
 				}
 			],
 			outputs: [
@@ -2121,14 +2121,14 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Vector"),
 					type: "VECTOR",
 					color: 0xff6363c7,
-					default_value: new f32_array_t([0.0, 0.0, 0.0])
+					default_value: f32_array_create_xyz(0.0, 0.0, 0.0)
 				}
 			],
 			buttons: [
 				{
 					name: "nodes_material_vector_curves_button",
 					type: "CUSTOM",
-					default_value: [[new f32_array_t([0.0, 0.0]), new f32_array_t([0.0, 0.0])], [new f32_array_t([0.0, 0.0]), new f32_array_t([0.0, 0.0])], [new f32_array_t([0.0, 0.0]), new f32_array_t([0.0, 0.0])]],
+					default_value: [[f32_array_create_xy(0.0, 0.0), f32_array_create_xy(0.0, 0.0)], [f32_array_create_xy(0.0, 0.0), f32_array_create_xy(0.0, 0.0)], [f32_array_create_xy(0.0, 0.0), f32_array_create_xy(0.0, 0.0)]],
 					output: 0,
 					height: 8.5
 				}
@@ -2213,7 +2213,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Color"),
 					type: "RGBA",
 					color: 0xffc7c729,
-					default_value: new f32_array_t([0.0, 0.0, 0.0, 1.0])
+					default_value: f32_array_create_xyzw(0.0, 0.0, 0.0, 1.0)
 				},
 				{
 					id: 0,
@@ -2228,7 +2228,7 @@ let nodes_material_list: zui_node_t[][] = [
 				{
 					name: "nodes_material_color_ramp_button",
 					type: "CUSTOM",
-					default_value: [new f32_array_t([1.0, 1.0, 1.0, 1.0, 0.0])],
+					default_value: [f32_array_create_xyzwv(1.0, 1.0, 1.0, 1.0, 0.0)],
 					data: 0,
 					output: 0,
 					height: 4.5
@@ -2249,7 +2249,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Color"),
 					type: "RGBA",
 					color: 0xffc7c729,
-					default_value: new f32_array_t([0.8, 0.8, 0.8, 1.0])
+					default_value: f32_array_create_xyzw(0.8, 0.8, 0.8, 1.0)
 				},
 				{
 					id: 0,
@@ -2257,7 +2257,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Mask Color"),
 					type: "RGBA",
 					color: 0xffc7c729,
-					default_value: new f32_array_t([0.8, 0.8, 0.8, 1.0])
+					default_value: f32_array_create_xyzw(0.8, 0.8, 0.8, 1.0)
 				},
 				{
 					id: 0,
@@ -2330,7 +2330,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Color"),
 					type: "RGBA",
 					color: 0xffc7c729,
-					default_value: new f32_array_t([0.8, 0.8, 0.8, 1.0])
+					default_value: f32_array_create_xyzw(0.8, 0.8, 0.8, 1.0)
 				}
 			],
 			buttons: []
@@ -2375,7 +2375,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Color"),
 					type: "RGBA",
 					color: 0xffc7c729,
-					default_value: new f32_array_t([0.8, 0.8, 0.8, 1.0])
+					default_value: f32_array_create_xyzw(0.8, 0.8, 0.8, 1.0)
 				}
 			],
 			buttons: []
@@ -2420,7 +2420,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Vector"),
 					type: "VECTOR",
 					color: 0xff6363c7,
-					default_value: new f32_array_t([0.0, 0.0, 0.0])
+					default_value: f32_array_create_xyz(0.0, 0.0, 0.0)
 				}
 			],
 			buttons: []
@@ -2558,7 +2558,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Color"),
 					type: "RGBA",
 					color: 0xffc7c729,
-					default_value: new f32_array_t([0.0, 0.0, 0.0, 0.0])
+					default_value: f32_array_create_xyzw(0.0, 0.0, 0.0, 0.0)
 				}
 			],
 			outputs: [
@@ -2587,7 +2587,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Color"),
 					type: "RGBA",
 					color: 0xffc7c729,
-					default_value: new f32_array_t([0.5, 0.5, 0.5, 1.0])
+					default_value: f32_array_create_xyzw(0.5, 0.5, 0.5, 1.0)
 				}
 			],
 			outputs: [
@@ -2632,7 +2632,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Color"),
 					type: "RGBA",
 					color: 0xffc7c729,
-					default_value: new f32_array_t([0.8, 0.8, 0.8, 1.0])
+					default_value: f32_array_create_xyzw(0.8, 0.8, 0.8, 1.0)
 				}
 			],
 			outputs: [
@@ -2677,7 +2677,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Vector"),
 					type: "VECTOR",
 					color: 0xff6363c7,
-					default_value: new f32_array_t([0.0, 0.0, 0.0])
+					default_value: f32_array_create_xyz(0.0, 0.0, 0.0)
 				}
 			],
 			outputs: [
@@ -2722,7 +2722,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Vector"),
 					type: "VECTOR",
 					color: 0xff6363c7,
-					default_value: new f32_array_t([0.0, 0.0, 0.0])
+					default_value: f32_array_create_xyz(0.0, 0.0, 0.0)
 				},
 				{
 					id: 0,
@@ -2730,7 +2730,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Vector"),
 					type: "VECTOR",
 					color: 0xff6363c7,
-					default_value: new f32_array_t([0.0, 0.0, 0.0])
+					default_value: f32_array_create_xyz(0.0, 0.0, 0.0)
 				}
 			],
 			outputs: [
@@ -2740,7 +2740,7 @@ let nodes_material_list: zui_node_t[][] = [
 					name: _tr("Vector"),
 					type: "VECTOR",
 					color: 0xff6363c7,
-					default_value: new f32_array_t([0.0, 0.0, 0.0])
+					default_value: f32_array_create_xyz(0.0, 0.0, 0.0)
 				},
 				{
 					id: 0,
@@ -2785,7 +2785,7 @@ let nodes_material_list: zui_node_t[][] = [
 
 function nodes_material_vector_curves_button(ui: zui_t, nodes: zui_nodes_t, node: zui_node_t) {
 	let but: zui_node_button_t = node.buttons[0];
-	let nhandle: zui_handle_t = zui_nest(zui_handle("nodesmaterial_0"), node.id);
+	let nhandle: zui_handle_t = zui_nest(zui_handle(__ID__), node.id);
 	zui_row([1 / 3, 1 / 3, 1 / 3]);
 	zui_radio(zui_nest(zui_nest(nhandle, 0), 1), 0, "X");
 	zui_radio(zui_nest(zui_nest(nhandle, 0), 1), 1, "Y");
@@ -2822,7 +2822,7 @@ function nodes_material_vector_curves_button(ui: zui_t, nodes: zui_nodes_t, node
 
 function nodes_material_color_ramp_button(ui: zui_t, nodes: zui_nodes_t, node: zui_node_t) {
 	let but: zui_node_button_t = node.buttons[0];
-	let nhandle: zui_handle_t = zui_nest(zui_handle("nodesmaterial_1"), node.id);
+	let nhandle: zui_handle_t = zui_nest(zui_handle(__ID__), node.id);
 	let nx: f32 = ui._x;
 	let ny: f32 = ui._y;
 
@@ -3032,7 +3032,7 @@ function nodes_material_get_socket_color(type: string): i32 {
 }
 
 function nodes_material_get_socket_default_value(type: string): any {
-	return type == "RGBA" ? new f32_array_t([0.8, 0.8, 0.8, 1.0]) : type == "VECTOR" ? new f32_array_t([0.0, 0.0, 0.0]) : 0.0;
+	return type == "RGBA" ? f32_array_create_xyzw(0.8, 0.8, 0.8, 1.0) : type == "VECTOR" ? f32_array_create_xyz(0.0, 0.0, 0.0) : 0.0;
 }
 
 function nodes_material_get_socket_name(type: string): string {

+ 32 - 32
base/Sources/project.ts

@@ -42,7 +42,7 @@ function project_open() {
 	});
 }
 
-function project_save(saveAndQuit: bool = false) {
+function project_save(save_and_quit: bool = false) {
 	if (project_filepath == "") {
 		///if krom_ios
 		let document_directory: string = krom_save_dialog("", "");
@@ -51,7 +51,7 @@ function project_save(saveAndQuit: bool = false) {
 		///elseif krom_android
 		project_filepath = krom_save_path() + "/" + sys_title() + ".arm";
 		///else
-		project_save_as(saveAndQuit);
+		project_save_as(save_and_quit);
 		return;
 		///end
 	}
@@ -63,12 +63,12 @@ function project_save(saveAndQuit: bool = false) {
 
 	let _init = function () {
 		export_arm_run_project();
-		if (saveAndQuit) sys_stop();
+		if (save_and_quit) sys_stop();
 	}
 	app_notify_on_init(_init);
 }
 
-function project_save_as(saveAndQuit: bool = false) {
+function project_save_as(save_and_quit: bool = false) {
 	ui_files_show("arm", true, false, function (path: string) {
 		let f: string = ui_files_filename;
 		if (f == "") {
@@ -78,14 +78,14 @@ function project_save_as(saveAndQuit: bool = false) {
 		if (!ends_with(project_filepath, ".arm")) {
 			project_filepath += ".arm";
 		}
-		project_save(saveAndQuit);
+		project_save(save_and_quit);
 	});
 }
 
 function project_new_box() {
 	///if (is_paint || is_sculpt)
 	ui_box_show_custom(function (ui: zui_t) {
-		if (zui_tab(zui_handle("project_0"), tr("New Project"))) {
+		if (zui_tab(zui_handle(__ID__), tr("New Project"))) {
 			if (project_mesh_list == null) {
 				project_mesh_list = file_read_directory(path_data() + path_sep + "meshes");
 				for (let i: i32 = 0; i < project_mesh_list.length; ++i) {
@@ -97,8 +97,8 @@ function project_new_box() {
 			}
 
 			zui_row([0.5, 0.5]);
-			context_raw.project_type = zui_combo(zui_handle("project_1", { position: context_raw.project_type }), project_mesh_list, tr("Template"), true);
-			context_raw.project_aspect_ratio = zui_combo(zui_handle("project_2", { position: context_raw.project_aspect_ratio }), ["1:1", "2:1", "1:2"], tr("Aspect Ratio"), true);
+			context_raw.project_type = zui_combo(zui_handle(__ID__, { position: context_raw.project_type }), project_mesh_list, tr("Template"), true);
+			context_raw.project_aspect_ratio = zui_combo(zui_handle(__ID__, { position: context_raw.project_aspect_ratio }), ["1:1", "2:1", "1:2"], tr("Aspect Ratio"), true);
 
 			zui_end_element();
 			zui_row([0.5, 0.5]);
@@ -120,7 +120,7 @@ function project_new_box() {
 	///end
 }
 
-function project_new(resetLayers: bool = true) {
+function project_new(reset_layers: bool = true) {
 	///if (krom_windows || krom_linux || krom_darwin)
 	sys_title_set(manifest_title);
 	///end
@@ -282,7 +282,7 @@ function project_new(resetLayers: bool = true) {
 	ui_base_hwnds[tab_area_t.SIDEBAR1].redraws = 2;
 	///end
 
-	if (resetLayers) {
+	if (reset_layers) {
 
 		///if (is_paint || is_sculpt)
 		let aspect_ratio_changed: bool = project_layers[0].texpaint.width != config_get_texture_res_x() || project_layers[0].texpaint.height != config_get_texture_res_y();
@@ -378,13 +378,13 @@ function project_import_brush() {
 }
 ///end
 
-function project_import_mesh(replaceExisting: bool = true, done: ()=>void = null) {
+function project_import_mesh(replace_existing: bool = true, done: ()=>void = null) {
 	ui_files_show(path_mesh_formats.join(","), false, false, function (path: string) {
-		project_import_mesh_box(path, replaceExisting, true, done);
+		project_import_mesh_box(path, replace_existing, true, done);
 	});
 }
 
-function project_import_mesh_box(path: string, replaceExisting: bool = true, clearLayers: bool = true, done: ()=>void = null) {
+function project_import_mesh_box(path: string, replace_existing: bool = true, clear_layers: bool = true, done: ()=>void = null) {
 
 	///if krom_ios
 	// Import immediately while access to resource is unlocked
@@ -393,10 +393,10 @@ function project_import_mesh_box(path: string, replaceExisting: bool = true, cle
 
 	ui_box_show_custom(function (ui: zui_t) {
 		let tab_vertical: bool = config_raw.touch_ui;
-		if (zui_tab(zui_handle("project_3"), tr("Import Mesh"), tab_vertical)) {
+		if (zui_tab(zui_handle(__ID__), tr("Import Mesh"), tab_vertical)) {
 
 			if (ends_with(to_lower_case(path), ".obj")) {
-				context_raw.split_by = zui_combo(zui_handle("project_4"), [
+				context_raw.split_by = zui_combo(zui_handle(__ID__), [
 					tr("Object"),
 					tr("Group"),
 					tr("Material"),
@@ -415,7 +415,7 @@ function project_import_mesh_box(path: string, replaceExisting: bool = true, cle
 			///if (is_paint || is_sculpt)
 			// if (ends_with(to_lower_case(path), ".fbx") || ends_with(to_lower_case(path), ".blend")) {
 			if (ends_with(to_lower_case(path), ".blend")) {
-				context_raw.parse_vcols = zui_check(zui_handle("project_6", { selected: context_raw.parse_vcols }), tr("Parse Vertex Colors"));
+				context_raw.parse_vcols = zui_check(zui_handle(__ID__, { selected: context_raw.parse_vcols }), tr("Parse Vertex Colors"));
 				if (ui.is_hovered) {
 					zui_tooltip(tr("Import vertex color data"));
 				}
@@ -430,10 +430,10 @@ function project_import_mesh_box(path: string, replaceExisting: bool = true, cle
 				ui_box_hide();
 				let do_import = function () {
 					///if (is_paint || is_sculpt)
-					import_mesh_run(path, clearLayers, replaceExisting);
+					import_mesh_run(path, clear_layers, replace_existing);
 					///end
 					///if is_lab
-					import_mesh_run(path, replaceExisting);
+					import_mesh_run(path, replace_existing);
 					///end
 					if (done != null) {
 						done();
@@ -468,7 +468,7 @@ function project_reimport_mesh() {
 function project_unwrap_mesh_box(mesh: any, done: (a: any)=>void, skip_ui: bool = false) {
 	ui_box_show_custom(function (ui: zui_t) {
 		let tab_vertical: bool = config_raw.touch_ui;
-		if (zui_tab(zui_handle("project_7"), tr("Unwrap Mesh"), tab_vertical)) {
+		if (zui_tab(zui_handle(__ID__), tr("Unwrap Mesh"), tab_vertical)) {
 
 			let unwrap_plugins: string[] = [];
 			if (box_preferences_files_plugin == null) {
@@ -482,7 +482,7 @@ function project_unwrap_mesh_box(mesh: any, done: (a: any)=>void, skip_ui: bool
 			}
 			array_push(unwrap_plugins, "equirect");
 
-			let unwrap_by: i32 = zui_combo(zui_handle("project_8"), unwrap_plugins, tr("Plugin"), true);
+			let unwrap_by: i32 = zui_combo(zui_handle(__ID__), unwrap_plugins, tr("Plugin"), true);
 
 			zui_row([0.5, 0.5]);
 			if (zui_button(tr("Cancel"))) {
@@ -517,22 +517,22 @@ function project_unwrap_mesh_box(mesh: any, done: (a: any)=>void, skip_ui: bool
 	});
 }
 
-function project_import_asset(filters: string = null, hdrAsEnvmap: bool = true) {
+function project_import_asset(filters: string = null, hdr_as_envmap: bool = true) {
 	if (filters == null) {
 		filters = path_texture_formats.join(",") + "," + path_mesh_formats.join(",");
 	}
 	ui_files_show(filters, false, true, function (path: string) {
-		import_asset_run(path, -1.0, -1.0, true, hdrAsEnvmap);
+		import_asset_run(path, -1.0, -1.0, true, hdr_as_envmap);
 	});
 }
 
-function project_import_swatches(replaceExisting: bool = false) {
+function project_import_swatches(replace_existing: bool = false) {
 	ui_files_show("arm,gpl", false, false, function (path: string) {
 		if (path_is_gimp_color_palette(path)) {
-			import_gpl_run(path, replaceExisting);
+			import_gpl_run(path, replace_existing);
 		}
 		else {
-			import_arm_run_swatches(path, replaceExisting);
+			import_arm_run_swatches(path, replace_existing);
 		}
 	});
 }
@@ -616,8 +616,8 @@ function project_is_atlas_object(p: mesh_object_t): bool {
 	return atlas_i == project_atlas_objects[array_index_of(project_paint_objects, p)];
 }
 
-function project_get_atlas_objects(objectMask: i32): mesh_object_t[] {
-	let atlas_name: string = project_get_used_atlases()[objectMask - project_paint_objects.length - 1];
+function project_get_atlas_objects(object_mask: i32): mesh_object_t[] {
+	let atlas_name: string = project_get_used_atlases()[object_mask - project_paint_objects.length - 1];
 	let atlas_i: i32 = array_index_of(project_atlas_names, atlas_name);
 	let visibles: mesh_object_t[] = [];
 	for (let i: i32 = 0; i < project_paint_objects.length; ++i) {
@@ -673,10 +673,10 @@ function project_set_default_swatches() {
 	}
 }
 
-function project_get_material_group_by_name(groupName: string): node_group_t {
+function project_get_material_group_by_name(group_name: string): node_group_t {
 	for (let i: i32 = 0; i < project_material_groups.length; ++i) {
 		let g: node_group_t = project_material_groups[i];
-		if (g.canvas.name == groupName) {
+		if (g.canvas.name == group_name) {
 			return g;
 		}
 	}
@@ -715,13 +715,13 @@ type node_group_t = {
 type project_format_t = {
 	version?: string;
 	assets?: string[]; // texture_assets
-	is_bgra?: Null<bool>; // Swapped red and blue channels for layer textures
+	is_bgra?: bool; // Swapped red and blue channels for layer textures
 	packed_assets?: packed_asset_t[];
 	envmap?: string; // Asset name
-	envmap_strength?: Null<f32>;
+	envmap_strength?: f32;
 	camera_world?: f32_array_t;
 	camera_origin?: f32_array_t;
-	camera_fov?: Null<f32>;
+	camera_fov?: f32;
 	swatches?: swatch_color_t[];
 
 	///if (is_paint || is_sculpt)

+ 9 - 9
base/Sources/tab_materials.ts

@@ -191,15 +191,15 @@ function tab_materials_draw_slots(mini: bool) {
 						tab_materials_delete_material(m);
 					}
 
-					let base_handle: zui_handle_t = zui_nest(zui_handle("tabmaterials_0"), m.id, {selected: m.paint_base});
-					let opac_handle: zui_handle_t = zui_nest(zui_handle("tabmaterials_1"), m.id, {selected: m.paint_opac});
-					let nor_handle: zui_handle_t = zui_nest(zui_handle("tabmaterials_2"), m.id, {selected: m.paint_nor});
-					let occ_handle: zui_handle_t = zui_nest(zui_handle("tabmaterials_3"), m.id, {selected: m.paint_occ});
-					let rough_handle: zui_handle_t = zui_nest(zui_handle("tabmaterials_4"), m.id, {selected: m.paint_rough});
-					let met_handle: zui_handle_t = zui_nest(zui_handle("tabmaterials_5"), m.id, {selected: m.paint_met});
-					let height_handle: zui_handle_t = zui_nest(zui_handle("tabmaterials_6"), m.id, {selected: m.paint_height});
-					let emis_handle: zui_handle_t = zui_nest(zui_handle("tabmaterials_7"), m.id, {selected: m.paint_emis});
-					let subs_handle: zui_handle_t = zui_nest(zui_handle("tabmaterials_8"), m.id, {selected: m.paint_subs});
+					let base_handle: zui_handle_t = zui_nest(zui_handle(__ID__), m.id, {selected: m.paint_base});
+					let opac_handle: zui_handle_t = zui_nest(zui_handle(__ID__), m.id, {selected: m.paint_opac});
+					let nor_handle: zui_handle_t = zui_nest(zui_handle(__ID__), m.id, {selected: m.paint_nor});
+					let occ_handle: zui_handle_t = zui_nest(zui_handle(__ID__), m.id, {selected: m.paint_occ});
+					let rough_handle: zui_handle_t = zui_nest(zui_handle(__ID__), m.id, {selected: m.paint_rough});
+					let met_handle: zui_handle_t = zui_nest(zui_handle(__ID__), m.id, {selected: m.paint_met});
+					let height_handle: zui_handle_t = zui_nest(zui_handle(__ID__), m.id, {selected: m.paint_height});
+					let emis_handle: zui_handle_t = zui_nest(zui_handle(__ID__), m.id, {selected: m.paint_emis});
+					let subs_handle: zui_handle_t = zui_nest(zui_handle(__ID__), m.id, {selected: m.paint_subs});
 					ui_menu_fill(ui);
 					m.paint_base = zui_check(base_handle, tr("Base Color"));
 					ui_menu_fill(ui);

+ 1 - 1
base/Sources/tab_meshes.ts

@@ -115,7 +115,7 @@ function tab_meshes_draw(htab: zui_handle_t) {
 
 		for (let i: i32 = 0; i < project_paint_objects.length; ++i) {
 			let o: mesh_object_t = project_paint_objects[i];
-			let h: zui_handle_t = zui_handle("tabmeshes_0");
+			let h: zui_handle_t = zui_handle(__ID__);
 			h.selected = o.base.visible;
 			o.base.visible = zui_check(h, o.base.name);
 			if (ui.is_hovered && ui.input_released_r) {

+ 8 - 8
base/Sources/tab_swatches.ts

@@ -132,7 +132,7 @@ function tab_swatches_draw(htab: zui_handle_t) {
 					if (time_time() - context_raw.select_time < 0.25) {
 						ui_menu_draw(function (ui: zui_t) {
 							ui.changed = false;
-							let h: zui_handle_t = zui_handle("tabswatches_0");
+							let h: zui_handle_t = zui_handle(__ID__);
 							h.color = context_raw.swatch.base;
 
 							context_raw.swatch.base = zui_color_wheel(h, false, null, 11 * ui.t.ELEMENT_H * zui_SCALE(ui), true, function () {
@@ -142,19 +142,19 @@ function tab_swatches_draw(htab: zui_handle_t) {
 									project_raw.swatches[i] = project_clone_swatch(color);
 								};
 							});
-							let hopacity: zui_handle_t = zui_handle("tabswatches_1");
+							let hopacity: zui_handle_t = zui_handle(__ID__);
 							hopacity.value = context_raw.swatch.opacity;
 							context_raw.swatch.opacity = zui_slider(hopacity, "Opacity", 0, 1, true);
-							let hocclusion: zui_handle_t = zui_handle("tabswatches_2");
+							let hocclusion: zui_handle_t = zui_handle(__ID__);
 							hocclusion.value = context_raw.swatch.occlusion;
 							context_raw.swatch.occlusion = zui_slider(hocclusion, "Occlusion", 0, 1, true);
-							let hroughness: zui_handle_t = zui_handle("tabswatches_3");
+							let hroughness: zui_handle_t = zui_handle(__ID__);
 							hroughness.value = context_raw.swatch.roughness;
 							context_raw.swatch.roughness = zui_slider(hroughness, "Roughness", 0, 1, true);
-							let hmetallic: zui_handle_t = zui_handle("tabswatches_4");
+							let hmetallic: zui_handle_t = zui_handle(__ID__);
 							hmetallic.value = context_raw.swatch.metallic;
 							context_raw.swatch.metallic = zui_slider(hmetallic, "Metallic", 0, 1, true);
-							let hheight: zui_handle_t = zui_handle("tabswatches_5");
+							let hheight: zui_handle_t = zui_handle(__ID__);
 							hheight.value = context_raw.swatch.height;
 							context_raw.swatch.height = zui_slider(hheight, "Height", 0, 1, true);
 
@@ -196,7 +196,7 @@ function tab_swatches_draw(htab: zui_handle_t) {
 							if (val < 0) {
 								val += 4294967296;
 							}
-							krom_copy_to_clipboard(val.toString(16));
+							krom_copy_to_clipboard(i32_to_string(val));
 						}
 						///end
 						else if (project_raw.swatches.length > 1 && ui_menu_button(ui, tr("Delete"), "delete")) {
@@ -221,7 +221,7 @@ function tab_swatches_draw(htab: zui_handle_t) {
 					if (val < 0) {
 						val += 4294967296;
 					}
-					zui_tooltip("#" + val.toString(16));
+					zui_tooltip("#" + i32_to_string_hex(val));
 				}
 			}
 		}

+ 4 - 4
base/Sources/ui_base.ts

@@ -610,7 +610,7 @@ function ui_base_update() {
 				///end
 
 				ui_menu_draw(function (ui: zui_t) {
-					let mode_handle: zui_handle_t = zui_handle("uibase_0");
+					let mode_handle: zui_handle_t = zui_handle(__ID__);
 					mode_handle.position = context_raw.viewport_mode;
 					zui_text(tr("Viewport Mode"), zui_align_t.RIGHT, ui.t.HIGHLIGHT_COL);
 					let modes: string[] = [
@@ -855,7 +855,7 @@ function ui_base_view_top() {
 }
 
 function ui_base_operator_search() {
-	let search_handle: zui_handle_t = zui_handle("uibase_1");
+	let search_handle: zui_handle_t = zui_handle(__ID__);
 	let first: bool = true;
 	ui_menu_draw(function (ui: zui_t) {
 		zui_fill(0, 0, ui._w / zui_SCALE(ui), ui.t.ELEMENT_H * 8, ui.t.SEPARATOR_COL);
@@ -1259,7 +1259,7 @@ function ui_base_render() {
 		ui_base_ui.input_enabled = true;
 		g2_end();
 		zui_begin(ui_base_ui);
-		if (zui_window(zui_handle("uibase_2"), 0, 0, 150, math_floor(zui_ELEMENT_H(ui_base_ui) + zui_ELEMENT_OFFSET(ui_base_ui) + 1))) {
+		if (zui_window(zui_handle(__ID__), 0, 0, 150, math_floor(zui_ELEMENT_H(ui_base_ui) + zui_ELEMENT_OFFSET(ui_base_ui) + 1))) {
 			if (zui_button(tr("Close"))) {
 				ui_base_toggle_distract_free();
 			}
@@ -1335,7 +1335,7 @@ function ui_base_draw_sidebar() {
 	if (config_raw.touch_ui) {
 		let width: i32 = config_raw.layout[layout_size_t.SIDEBAR_W];
 		let height: i32 = math_floor(zui_ELEMENT_H(ui_base_ui) + zui_ELEMENT_OFFSET(ui_base_ui));
-		if (zui_window(zui_handle("uibase_3"), sys_width() - width, sys_height() - height, width, height + 1)) {
+		if (zui_window(zui_handle(__ID__), sys_width() - width, sys_height() - height, width, height + 1)) {
 			ui_base_ui._w = width;
 			let _BUTTON_H: i32 = ui_base_ui.t.BUTTON_H;
 			let _BUTTON_COL: i32 = ui_base_ui.t.BUTTON_COL;

+ 2 - 2
base/Sources/ui_box.ts

@@ -76,8 +76,8 @@ function ui_box_render() {
 		if (zui_window(ui_box_hwnd, left, top, mw, mh, ui_box_draggable)) {
 			ui._y += 10;
 			let tab_vertical: bool = config_raw.touch_ui;
-			if (zui_tab(zui_handle("uibox_0"), ui_box_title, tab_vertical)) {
-				let htext: zui_handle_t = zui_handle("uibox_1");
+			if (zui_tab(zui_handle(__ID__), ui_box_title, tab_vertical)) {
+				let htext: zui_handle_t = zui_handle(__ID__);
 				htext.text = ui_box_text;
 				ui_box_copyable ?
 					zui_text_area(htext, zui_align_t.LEFT, false) :

+ 24 - 24
base/Sources/ui_header.ts

@@ -125,7 +125,7 @@ function ui_header_draw_tool_properties(ui: zui_t) {
 		let height_picked: f32 = math_round(context_raw.picked_color.height * 100) / 100;
 		let opacity_picked: f32 = math_round(context_raw.picked_color.opacity * 100) / 100;
 
-		let h: zui_handle_t = zui_handle("uiheader_0");
+		let h: zui_handle_t = zui_handle(__ID__);
 		let color: color_t = 0xffffffff;
 		color = color_set_rb(color, base_r_picked * 255);
 		color = color_set_gb(color, base_g_picked * 255);
@@ -169,7 +169,7 @@ function ui_header_draw_tool_properties(ui: zui_t) {
 		zui_text(tr("Metallic") + " (" + metallic_picked + ")");
 		zui_text(tr("Height") + " (" + height_picked + ")");
 		zui_text(tr("Opacity") + " (" + opacity_picked + ")");
-		context_raw.picker_select_material = zui_check(zui_handle("uiheader_1", { selected: context_raw.picker_select_material }), tr("Select Material"));
+		context_raw.picker_select_material = zui_check(zui_handle(__ID__, { selected: context_raw.picker_select_material }), tr("Select Material"));
 		zui_combo(context_raw.picker_mask_handle, [tr("None"), tr("Material")], tr("Mask"), true);
 		if (context_raw.picker_mask_handle.changed) {
 			make_material_parse_paint_material();
@@ -203,7 +203,7 @@ function ui_header_draw_tool_properties(ui: zui_t) {
 			///end
 		}
 
-		let bake_handle: zui_handle_t = zui_handle("uiheader_2", { position: context_raw.bake_type });
+		let bake_handle: zui_handle_t = zui_handle(__ID__, { position: context_raw.bake_type });
 		let bakes: string[] = [
 			tr("AO"),
 			tr("Curvature"),
@@ -238,25 +238,25 @@ function ui_header_draw_tool_properties(ui: zui_t) {
 
 		///if (krom_direct3d12 || krom_vulkan || krom_metal)
 		if (rt_bake) {
-			let samples_handle: zui_handle_t = zui_handle("uiheader_3", { value: context_raw.bake_samples });
+			let samples_handle: zui_handle_t = zui_handle(__ID__, { value: context_raw.bake_samples });
 			context_raw.bake_samples = math_floor(zui_slider(samples_handle, tr("Samples"), 1, 512, true, 1));
 		}
 		///end
 
 		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) {
-			let bake_up_axis_handle: zui_handle_t = zui_handle("uiheader_4", { position: context_raw.bake_up_axis });
+			let bake_up_axis_handle: zui_handle_t = zui_handle(__ID__, { position: context_raw.bake_up_axis });
 			context_raw.bake_up_axis = zui_combo(bake_up_axis_handle, [tr("Z"), tr("Y")], tr("Up Axis"), true);
 		}
 		if (context_raw.bake_type == bake_type_t.AO || context_raw.bake_type == bake_type_t.CURVATURE) {
-			let bake_axis_handle: zui_handle_t = zui_handle("uiheader_5", { position: context_raw.bake_axis });
+			let bake_axis_handle: zui_handle_t = zui_handle(__ID__, { position: context_raw.bake_axis });
 			context_raw.bake_axis = zui_combo(bake_axis_handle, [tr("XYZ"), tr("X"), tr("Y"), tr("Z"), tr("-X"), tr("-Y"), tr("-Z")], tr("Axis"), true);
 		}
 		if (context_raw.bake_type == bake_type_t.AO) {
-			let strength_handle: zui_handle_t = zui_handle("uiheader_6", { value: context_raw.bake_ao_strength });
+			let strength_handle: zui_handle_t = zui_handle(__ID__, { value: context_raw.bake_ao_strength });
 			context_raw.bake_ao_strength = zui_slider(strength_handle, tr("Strength"), 0.0, 2.0, true);
-			let radius_handle: zui_handle_t = zui_handle("uiheader_7", { value: context_raw.bake_ao_radius });
+			let radius_handle: zui_handle_t = zui_handle(__ID__, { value: context_raw.bake_ao_radius });
 			context_raw.bake_ao_radius = zui_slider(radius_handle, tr("Radius"), 0.0, 2.0, true);
-			let offset_handle: zui_handle_t = zui_handle("uiheader_8", { value: context_raw.bake_ao_offset });
+			let offset_handle: zui_handle_t = zui_handle(__ID__, { value: context_raw.bake_ao_offset });
 			context_raw.bake_ao_offset = zui_slider(offset_handle, tr("Offset"), 0.0, 2.0, true);
 		}
 		///if (krom_direct3d12 || krom_vulkan || krom_metal)
@@ -275,13 +275,13 @@ function ui_header_draw_tool_properties(ui: zui_t) {
 		}
 		///end
 		if (context_raw.bake_type == bake_type_t.CURVATURE) {
-			let strength_handle: zui_handle_t = zui_handle("uiheader_9", { value: context_raw.bake_curv_strength });
+			let strength_handle: zui_handle_t = zui_handle(__ID__, { value: context_raw.bake_curv_strength });
 			context_raw.bake_curv_strength = zui_slider(strength_handle, tr("Strength"), 0.0, 2.0, true);
-			let radius_handle: zui_handle_t = zui_handle("uiheader_10", { value: context_raw.bake_curv_radius });
+			let radius_handle: zui_handle_t = zui_handle(__ID__, { value: context_raw.bake_curv_radius });
 			context_raw.bake_curv_radius = zui_slider(radius_handle, tr("Radius"), 0.0, 2.0, true);
-			let offset_handle: zui_handle_t = zui_handle("uiheader_11", { value: context_raw.bake_curv_offset });
+			let offset_handle: zui_handle_t = zui_handle(__ID__, { value: context_raw.bake_curv_offset });
 			context_raw.bake_curv_offset = zui_slider(offset_handle, tr("Offset"), -2.0, 2.0, true);
-			let smooth_handle: zui_handle_t = zui_handle("uiheader_12", { value: context_raw.bake_curv_smooth });
+			let smooth_handle: zui_handle_t = zui_handle(__ID__, { value: context_raw.bake_curv_smooth });
 			context_raw.bake_curv_smooth = math_floor(zui_slider(smooth_handle, tr("Smooth"), 0, 5, false, 1));
 		}
 		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) {
@@ -290,7 +290,7 @@ function ui_header_draw_tool_properties(ui: zui_t) {
 				let p: mesh_object_t = project_paint_objects[i];
 				array_push(ar, p.base.name);
 			}
-			let poly_handle: zui_handle_t = zui_handle("uiheader_13", { position: context_raw.bake_high_poly });
+			let poly_handle: zui_handle_t = zui_handle(__ID__, { position: context_raw.bake_high_poly });
 			context_raw.bake_high_poly = zui_combo(poly_handle, ar, tr("High Poly"));
 		}
 		if (ui.changed) {
@@ -340,7 +340,7 @@ function ui_header_draw_tool_properties(ui: zui_t) {
 			context_raw.tool == workspace_tool_t.FILL   ||
 			context_raw.tool == workspace_tool_t.DECAL  ||
 			context_raw.tool == workspace_tool_t.TEXT) {
-			let brush_scale_handle: zui_handle_t = zui_handle("uiheader_14", { value: context_raw.brush_scale });
+			let brush_scale_handle: zui_handle_t = zui_handle(__ID__, { value: context_raw.brush_scale });
 			context_raw.brush_scale = zui_slider(brush_scale_handle, tr("UV Scale"), 0.01, 5.0, true);
 			if (brush_scale_handle.changed) {
 				if (context_raw.tool == workspace_tool_t.DECAL || context_raw.tool == workspace_tool_t.TEXT) {
@@ -371,11 +371,11 @@ function ui_header_draw_tool_properties(ui: zui_t) {
 		}
 
 		if (context_raw.tool == workspace_tool_t.BRUSH || context_raw.tool == workspace_tool_t.ERASER || context_raw.tool == workspace_tool_t.CLONE || decal_mask) {
-			context_raw.brush_hardness = zui_slider(zui_handle("uiheader_15", { value: context_raw.brush_hardness }), tr("Hardness"), 0.0, 1.0, true);
+			context_raw.brush_hardness = zui_slider(zui_handle(__ID__, { value: context_raw.brush_hardness }), tr("Hardness"), 0.0, 1.0, true);
 		}
 
 		if (context_raw.tool != workspace_tool_t.ERASER) {
-			let brush_blending_handle: zui_handle_t = zui_handle("uiheader_16", { value: context_raw.brush_blending });
+			let brush_blending_handle: zui_handle_t = zui_handle(__ID__, { value: context_raw.brush_blending });
 			context_raw.brush_blending = zui_combo(brush_blending_handle, [
 				tr("Mix"),
 				tr("Darken"),
@@ -402,14 +402,14 @@ function ui_header_draw_tool_properties(ui: zui_t) {
 		}
 
 		if (context_raw.tool == workspace_tool_t.BRUSH || context_raw.tool == workspace_tool_t.FILL) {
-			let paint_handle: zui_handle_t = zui_handle("uiheader_17");
+			let paint_handle: zui_handle_t = zui_handle(__ID__);
 			context_raw.brush_paint = zui_combo(paint_handle, [tr("UV Map"), tr("Triplanar"), tr("Project")], tr("TexCoord"));
 			if (paint_handle.changed) {
 				make_material_parse_paint_material();
 			}
 		}
 		if (context_raw.tool == workspace_tool_t.TEXT) {
-			let h: zui_handle_t = zui_handle("uiheader_18");
+			let h: zui_handle_t = zui_handle(__ID__);
 			h.text = context_raw.text_tool_text;
 			let w: i32 = ui._w;
 			if (ui.text_selected_handle_ptr == h.ptr || ui.submit_text_handle_ptr == h.ptr) {
@@ -452,15 +452,15 @@ function ui_header_draw_tool_properties(ui: zui_t) {
 			}
 			ui._w = math_floor((touch_header ? 54 : 60) * sc);
 
-			let xray_handle: zui_handle_t = zui_handle("uiheader_19", { selected: context_raw.xray });
+			let xray_handle: zui_handle_t = zui_handle(__ID__, { selected: context_raw.xray });
 			context_raw.xray = zui_check(xray_handle, tr("X-Ray"));
 			if (xray_handle.changed) {
 				make_material_parse_paint_material();
 			}
 
-			let sym_x_handle: zui_handle_t = zui_handle("uiheader_20", { selected: false });
-			let sym_y_handle: zui_handle_t = zui_handle("uiheader_21", { selected: false });
-			let sym_z_handle: zui_handle_t = zui_handle("uiheader_22", { selected: false });
+			let sym_x_handle: zui_handle_t = zui_handle(__ID__, { selected: false });
+			let sym_y_handle: zui_handle_t = zui_handle(__ID__, { selected: false });
+			let sym_z_handle: zui_handle_t = zui_handle(__ID__, { selected: false });
 
 			if (config_raw.layout[layout_size_t.HEADER] == 1) {
 				if (config_raw.touch_ui) {
@@ -500,7 +500,7 @@ function ui_header_draw_tool_properties(ui: zui_t) {
 		///if arm_physics
 		if (context_raw.tool == workspace_tool_t.PARTICLE) {
 			ui._x += 10 * zui_SCALE(ui);
-			let phys_handle: zui_handle_t = zui_handle("uiheader_23", { selected: false });
+			let phys_handle: zui_handle_t = zui_handle(__ID__, { selected: false });
 			context_raw.particle_physics = zui_check(phys_handle, tr("Physics"));
 			if (phys_handle.changed) {
 				util_particle_init_physics();

+ 15 - 15
base/Sources/ui_menu.ts

@@ -163,7 +163,7 @@ function ui_menu_render() {
 
 			ui_menu_fill(ui);
 			let p: world_data_t = scene_world;
-			let env_handle: zui_handle_t = zui_handle("uimenu_0");
+			let env_handle: zui_handle_t = zui_handle(__ID__);
 			env_handle.value = p.strength;
 			ui_menu_align(ui);
 			p.strength = zui_slider(env_handle, tr("Environment"), 0.0, 8.0, true);
@@ -172,7 +172,7 @@ function ui_menu_render() {
 			}
 
 			ui_menu_fill(ui);
-			let enva_handle: zui_handle_t = zui_handle("uimenu_1");
+			let enva_handle: zui_handle_t = zui_handle(__ID__);
 			enva_handle.value = context_raw.envmap_angle / math_pi() * 180.0;
 			if (enva_handle.value < 0) {
 				enva_handle.value += (math_floor(-enva_handle.value / 360) + 1) * 360;
@@ -195,7 +195,7 @@ function ui_menu_render() {
 				let light: light_object_t = scene_lights[0];
 
 				ui_menu_fill(ui);
-				let lhandle: zui_handle_t = zui_handle("uimenu_2");
+				let lhandle: zui_handle_t = zui_handle(__ID__);
 				let scale: f32 = 1333;
 				lhandle.value = light.data.strength / scale;
 				lhandle.value = math_floor(lhandle.value * 100) / 100;
@@ -207,7 +207,7 @@ function ui_menu_render() {
 
 				ui_menu_fill(ui);
 				light = scene_lights[0];
-				let lahandle: zui_handle_t = zui_handle("uimenu_3");
+				let lahandle: zui_handle_t = zui_handle(__ID__);
 				lahandle.value = context_raw.light_angle / math_pi() * 180;
 				ui_menu_align(ui);
 				let new_angle: f32 = zui_slider(lahandle, tr("Light Angle"), 0.0, 360.0, true, 1) / 180 * math_pi();
@@ -232,7 +232,7 @@ function ui_menu_render() {
 				}
 
 				ui_menu_fill(ui);
-				let sxhandle: zui_handle_t = zui_handle("uimenu_4");
+				let sxhandle: zui_handle_t = zui_handle(__ID__);
 				sxhandle.value = light.data.size;
 				ui_menu_align(ui);
 				light.data.size = zui_slider(sxhandle, tr("Light Size"), 0.0, 4.0, true);
@@ -243,7 +243,7 @@ function ui_menu_render() {
 
 			///if (is_paint || is_sculpt)
 			ui_menu_fill(ui);
-			let split_view_handle: zui_handle_t = zui_handle("uimenu_5", { selected: context_raw.split_view });
+			let split_view_handle: zui_handle_t = zui_handle(__ID__, { selected: context_raw.split_view });
 			context_raw.split_view = zui_check(split_view_handle, " " + tr("Split View"));
 			if (split_view_handle.changed) {
 				base_resize();
@@ -252,7 +252,7 @@ function ui_menu_render() {
 
 			///if is_lab
 			ui_menu_fill(ui);
-			let brush_scale_handle: zui_handle_t = zui_handle("uimenu_6", { value: context_raw.brush_scale });
+			let brush_scale_handle: zui_handle_t = zui_handle(__ID__, { value: context_raw.brush_scale });
 			ui_menu_align(ui);
 			context_raw.brush_scale = zui_slider(brush_scale_handle, tr("UV Scale"), 0.01, 5.0, true);
 			if (brush_scale_handle.changed) {
@@ -265,14 +265,14 @@ function ui_menu_render() {
 			///end
 
 			ui_menu_fill(ui);
-			let cull_handle: zui_handle_t = zui_handle("uimenu_7", { selected: context_raw.cull_backfaces });
+			let cull_handle: zui_handle_t = zui_handle(__ID__, { selected: context_raw.cull_backfaces });
 			context_raw.cull_backfaces = zui_check(cull_handle, " " + tr("Cull Backfaces"));
 			if (cull_handle.changed) {
 				make_material_parse_mesh_material();
 			}
 
 			ui_menu_fill(ui);
-			let filter_handle: zui_handle_t = zui_handle("uimenu_8", { selected: context_raw.texture_filter });
+			let filter_handle: zui_handle_t = zui_handle(__ID__, { selected: context_raw.texture_filter });
 			context_raw.texture_filter = zui_check(filter_handle, " " + tr("Filter Textures"));
 			if (filter_handle.changed) {
 				make_material_parse_paint_material();
@@ -300,7 +300,7 @@ function ui_menu_render() {
 			///end
 
 			ui_menu_fill(ui);
-			let compass_handle: zui_handle_t = zui_handle("uimenu_9", { selected: context_raw.show_compass });
+			let compass_handle: zui_handle_t = zui_handle(__ID__, { selected: context_raw.show_compass });
 			context_raw.show_compass = zui_check(compass_handle, " " + tr("Compass"));
 			if (compass_handle.changed) {
 				context_raw.ddirty = 2;
@@ -326,7 +326,7 @@ function ui_menu_render() {
 			}
 		}
 		else if (ui_menu_category == menu_category_t.MODE) {
-			let mode_handle: zui_handle_t = zui_handle("uimenu_10");
+			let mode_handle: zui_handle_t = zui_handle(__ID__);
 			mode_handle.position = context_raw.viewport_mode;
 			let modes: string[] = [
 				tr("Lit"),
@@ -428,7 +428,7 @@ function ui_menu_render() {
 
 			ui_menu_fill(ui);
 			let cam: camera_object_t = scene_camera;
-			context_raw.fov_handle = zui_handle("uimenu_11", { value: math_floor(cam.data.fov * 100) / 100 });
+			context_raw.fov_handle = zui_handle(__ID__, { value: math_floor(cam.data.fov * 100) / 100 });
 			ui_menu_align(ui);
 			cam.data.fov = zui_slider(context_raw.fov_handle, tr("FoV"), 0.3, 1.4, true);
 			if (context_raw.fov_handle.changed) {
@@ -437,7 +437,7 @@ function ui_menu_render() {
 
 			ui_menu_fill(ui);
 			ui_menu_align(ui);
-			let camera_controls_handle: zui_handle_t = zui_handle("uimenu_12");
+			let camera_controls_handle: zui_handle_t = zui_handle(__ID__);
 			camera_controls_handle.position = context_raw.camera_controls;
 			context_raw.camera_controls = zui_inline_radio(camera_controls_handle, [tr("Orbit"), tr("Rotate"), tr("Fly")], zui_align_t.LEFT);
 
@@ -560,13 +560,13 @@ function ui_menu_render() {
 
 				ui_box_show_custom(function (ui: zui_t) {
 					let tab_vertical: bool = config_raw.touch_ui;
-					if (zui_tab(zui_handle("uimenu_13"), tr("About"), tab_vertical)) {
+					if (zui_tab(zui_handle(__ID__), tr("About"), tab_vertical)) {
 
 						let img: image_t = data_get_image("badge.k");
 						zui_image(img);
 						zui_end_element();
 
-						zui_text_area(zui_handle("uimenu_14", { text: msg }), zui_align_t.LEFT, false);
+						zui_text_area(zui_handle(__ID__, { text: msg }), zui_align_t.LEFT, false);
 
 						zui_row([1 / 3, 1 / 3, 1 / 3]);
 

+ 14 - 14
base/Sources/ui_nodes.ts

@@ -109,14 +109,14 @@ function ui_nodes_on_socket_released(socket_id: i32) {
 			base_notify_on_next_frame(function () {
 				ui_menu_draw(function (ui: zui_t) {
 					if (ui_menu_button(ui, tr("Edit"))) {
-						let htype: zui_handle_t = zui_handle("uinodes_0");
-						let hname: zui_handle_t = zui_handle("uinodes_1");
-						let hmin: zui_handle_t = zui_handle("uinodes_2");
-						let hmax: zui_handle_t = zui_handle("uinodes_3");
-						let hval0: zui_handle_t = zui_handle("uinodes_4");
-						let hval1: zui_handle_t = zui_handle("uinodes_5");
-						let hval2: zui_handle_t = zui_handle("uinodes_6");
-						let hval3: zui_handle_t = zui_handle("uinodes_7");
+						let htype: zui_handle_t = zui_handle(__ID__);
+						let hname: zui_handle_t = zui_handle(__ID__);
+						let hmin: zui_handle_t = zui_handle(__ID__);
+						let hmax: zui_handle_t = zui_handle(__ID__);
+						let hval0: zui_handle_t = zui_handle(__ID__);
+						let hval1: zui_handle_t = zui_handle(__ID__);
+						let hval2: zui_handle_t = zui_handle(__ID__);
+						let hval3: zui_handle_t = zui_handle(__ID__);
 						htype.position = socket.type == "RGBA" ? 0 : socket.type == "VECTOR" ? 1 : 2;
 						hname.text = socket.name;
 						hmin.value = socket.min;
@@ -135,7 +135,7 @@ function ui_nodes_on_socket_released(socket_id: i32) {
 						base_notify_on_next_frame(function () {
 							zui_end_input();
 							ui_box_show_custom(function (ui: zui_t) {
-								if (zui_tab(zui_handle("uinodes_8"), tr("Socket"))) {
+								if (zui_tab(zui_handle(__ID__), tr("Socket"))) {
 									let type: i32 = zui_combo(htype, [tr("Color"), tr("Vector"), tr("Value")], tr("Type"), true);
 									if (htype.changed) {
 										hname.text = type == 0 ? tr("Color") : type == 1 ? tr("Vector") : tr("Value");
@@ -150,14 +150,14 @@ function ui_nodes_on_socket_released(socket_id: i32) {
 										zui_float_input(hval1, tr("G"));
 										zui_float_input(hval2, tr("B"));
 										zui_float_input(hval3, tr("A"));
-										default_value = new f32_array_t([hval0.value, hval1.value, hval2.value, hval3.value]);
+										default_value = f32_array_create_xyzw(hval0.value, hval1.value, hval2.value, hval3.value);
 									}
 									else if (type == 1) {
 										zui_row([1 / 3, 1 / 3, 1 / 3]);
 										hval0.value = zui_float_input(hval0, tr("X"));
 										hval1.value = zui_float_input(hval1, tr("Y"));
 										hval2.value = zui_float_input(hval2, tr("Z"));
-										default_value = new f32_array_t([hval0.value, hval1.value, hval2.value]);
+										default_value = f32_array_create_xyz(hval0.value, hval1.value, hval2.value);
 									}
 									else {
 										default_value = zui_float_input(hval0, tr("default_value"));
@@ -533,7 +533,7 @@ function ui_nodes_canvas_changed() {
 }
 
 function ui_nodes_node_search(x: i32 = -1, y: i32 = -1, done: ()=>void = null) {
-	let search_handle: zui_handle_t = zui_handle("uinodes_9");
+	let search_handle: zui_handle_t = zui_handle(__ID__);
 	let first: bool = true;
 	ui_menu_draw(function (ui: zui_t) {
 		g2_set_color(ui.t.SEPARATOR_COL);
@@ -798,7 +798,7 @@ function ui_nodes_render() {
 
 	if (zui_window(ui_nodes_hwnd, ui_nodes_wx, ui_nodes_wy, ui_nodes_ww, ui_nodes_wh)) {
 
-		zui_tab(zui_handle("uinodes_10"), tr("Nodes"));
+		zui_tab(zui_handle(__ID__), tr("Nodes"));
 
 		// Grid
 		g2_set_color(0xffffffff);
@@ -994,7 +994,7 @@ function ui_nodes_render() {
 
 		///if (is_paint || is_sculpt)
 		// Editable canvas name
-		let h: zui_handle_t = zui_handle("uinodes_11");
+		let h: zui_handle_t = zui_handle(__ID__);
 		h.text = c.name;
 		ui_nodes_ui._w = math_floor(math_min(g2_font_width(ui_nodes_ui.font, ui_nodes_ui.font_size, h.text) + 15 * zui_SCALE(ui_nodes_ui), 100 * zui_SCALE(ui_nodes_ui)));
 		let new_name: string = zui_text_input(h, "");

+ 6 - 6
base/Sources/ui_view2d.ts

@@ -113,7 +113,7 @@ function ui_view2d_render() {
 
 	if (zui_window(ui_view2d_hwnd, ui_view2d_wx, ui_view2d_wy, ui_view2d_ww, ui_view2d_wh)) {
 
-		zui_tab(zui_handle("uiview2d_0"), tr("2D View"));
+		zui_tab(zui_handle(__ID__), tr("2D View"));
 
 		// Grid
 		g2_set_color(0xffffffff);
@@ -286,7 +286,7 @@ function ui_view2d_render() {
 		ui_view2d_ui._w = ew;
 
 		// Editable layer name
-		let h: zui_handle_t = zui_handle("uiview2d_1");
+		let h: zui_handle_t = zui_handle(__ID__);
 
 		///if (is_paint || is_sculpt)
 		let text: string = ui_view2d_type == view_2d_type_t.NODE ? context_raw.node_preview_name : h.text;
@@ -341,7 +341,7 @@ function ui_view2d_render() {
 
 		///if (is_paint || is_sculpt)
 		if (ui_view2d_type == view_2d_type_t.LAYER) {
-			ui_view2d_layer_mode = zui_combo(zui_handle("uiview2d_2", { position: ui_view2d_layer_mode }), [
+			ui_view2d_layer_mode = zui_combo(zui_handle(__ID__, { position: ui_view2d_layer_mode }), [
 				tr("Visible"),
 				tr("Selected"),
 			], tr("Layers"));
@@ -349,7 +349,7 @@ function ui_view2d_render() {
 			ui_view2d_ui._y = 2 + start_y;
 
 			if (!slot_layer_is_mask(context_raw.layer)) {
-				ui_view2d_tex_type = zui_combo(zui_handle("uiview2d_3", { position: ui_view2d_tex_type }), [
+				ui_view2d_tex_type = zui_combo(zui_handle(__ID__, { position: ui_view2d_tex_type }), [
 					tr("Base Color"),
 					tr("Normal Map"),
 					tr("Occlusion"),
@@ -363,13 +363,13 @@ function ui_view2d_render() {
 			}
 
 			ui_view2d_ui._w = math_floor(ew * 0.7 + 3);
-			ui_view2d_uvmap_show = zui_check(zui_handle("uiview2d_4", { selected: ui_view2d_uvmap_show }), tr("UV Map"));
+			ui_view2d_uvmap_show = zui_check(zui_handle(__ID__, { selected: ui_view2d_uvmap_show }), tr("UV Map"));
 			ui_view2d_ui._x += ew * 0.7 + 3;
 			ui_view2d_ui._y = 2 + start_y;
 		}
 		///end
 
-		ui_view2d_tiled_show = zui_check(zui_handle("uiview2d_5", { selected: ui_view2d_tiled_show }), tr("Tiled"));
+		ui_view2d_tiled_show = zui_check(zui_handle(__ID__, { selected: ui_view2d_tiled_show }), tr("Tiled"));
 		ui_view2d_ui._x += ew * 0.7 + 3;
 		ui_view2d_ui._y = 2 + start_y;
 

+ 4 - 4
base/Sources/uniforms_ext.ts

@@ -12,14 +12,14 @@ function uniforms_ext_init() {
 	uniforms_tex_links = uniforms_ext_tex_link;
 }
 
-function uniforms_ext_i32_link(object: object_t, mat: material_data_t, link: string): Null<i32> {
+function uniforms_ext_i32_link(object: object_t, mat: material_data_t, link: string): i32 {
 	if (link == "_bloomCurrentMip") {
 		return render_path_base_bloom_current_mip;
 	}
-	return null;
+	return 0;
 }
 
-function uniforms_ext_f32_link(object: object_t, mat: material_data_t, link: string): Null<f32> {
+function uniforms_ext_f32_link(object: object_t, mat: material_data_t, link: string): f32 {
 	if (link == "_brushRadius") {
 		///if (is_paint || is_sculpt)
 		let decal: bool = context_raw.tool == workspace_tool_t.DECAL || context_raw.tool == workspace_tool_t.TEXT;
@@ -146,7 +146,7 @@ function uniforms_ext_f32_link(object: object_t, mat: material_data_t, link: str
 			return result;
 		}
 	}
-	return null;
+	return 0.0;
 }
 
 function uniforms_ext_vec2_link(object: object_t, mat: material_data_t, link: string): vec4_t {

+ 1 - 1
base/Sources/util_particle.ts

@@ -14,7 +14,7 @@ function util_particle_init() {
 		lifetime: 400,
 		lifetime_random: 0.5,
 		emit_from: 1,
-		object_align_factor: new f32_array_t([0, 0, -40]),
+		object_align_factor: f32_array_create_xyz(0, 0, -40),
 		factor_random: 2.0,
 		physics_type: 0,
 		particle_size: 1.0,