Prechádzať zdrojové kódy

Do not use macros in zui

luboslenco 1 rok pred
rodič
commit
0f5056e0e0

+ 19 - 19
armorforge/Sources/arm/ui/TabObjects.hx

@@ -26,7 +26,7 @@ class TabObjects {
 			}
 			ui.endSticky();
 
-			if (ui.panel(Id.handle({selected: true}), "Outliner")) {
+			if (ui.panel(Id.handle("tabobjects_0", {selected: true}), "Outliner")) {
 				ui.indent();
 				ui._y -= ui.ELEMENT_OFFSET();
 
@@ -125,17 +125,17 @@ class TabObjects {
 					}
 				}
 				for (c in iron.Scene.active.root.children) {
-					drawList(Id.handle(), c);
+					drawList(Id.handle("tabobjects_1"), c);
 				}
 
 				ui.unindent();
 			}
 
-			if (ui.panel(Id.handle({selected: true}), 'Properties')) {
+			if (ui.panel(Id.handle("tabobjects_2", {selected: true}), 'Properties')) {
 				ui.indent();
 
 				if (Context.raw.selectedObject != null) {
-					var h = Id.handle();
+					var h = Id.handle("tabobjects_3");
 					h.selected = Context.raw.selectedObject.visible;
 					Context.raw.selectedObject.visible = ui.check(h, "Visible");
 
@@ -151,17 +151,17 @@ class TabObjects {
 					ui.row([1 / 4, 1 / 4, 1 / 4, 1 / 4]);
 					ui.text("Loc");
 
-					h = Id.handle();
+					h = Id.handle("tabobjects_4");
 					h.text = roundfp(localPos.x) + "";
 					f = Std.parseFloat(ui.textInput(h, "X"));
 					if (h.changed) localPos.x = f;
 
-					h = Id.handle();
+					h = Id.handle("tabobjects_5");
 					h.text = roundfp(localPos.y) + "";
 					f = Std.parseFloat(ui.textInput(h, "Y"));
 					if (h.changed) localPos.y = f;
 
-					h = Id.handle();
+					h = Id.handle("tabobjects_6");
 					h.text = roundfp(localPos.z) + "";
 					f = Std.parseFloat(ui.textInput(h, "Z"));
 					if (h.changed) localPos.z = f;
@@ -169,18 +169,18 @@ class TabObjects {
 					ui.row([1 / 4, 1 / 4, 1 / 4, 1 / 4]);
 					ui.text("Rotation");
 
-					h = Id.handle();
+					h = Id.handle("tabobjects_7");
 					h.text = roundfp(rot.x) + "";
 					f = Std.parseFloat(ui.textInput(h, "X"));
 					var changed = false;
 					if (h.changed) { changed = true; rot.x = f; }
 
-					h = Id.handle();
+					h = Id.handle("tabobjects_8");
 					h.text = roundfp(rot.y) + "";
 					f = Std.parseFloat(ui.textInput(h, "Y"));
 					if (h.changed) { changed = true; rot.y = f; }
 
-					h = Id.handle();
+					h = Id.handle("tabobjects_9");
 					h.text = roundfp(rot.z) + "";
 					f = Std.parseFloat(ui.textInput(h, "Z"));
 					if (h.changed) { changed = true; rot.z = f; }
@@ -198,17 +198,17 @@ class TabObjects {
 					ui.row([1 / 4, 1 / 4, 1 / 4, 1 / 4]);
 					ui.text("Scale");
 
-					h = Id.handle();
+					h = Id.handle("tabobjects_10");
 					h.text = roundfp(scale.x) + "";
 					f = Std.parseFloat(ui.textInput(h, "X"));
 					if (h.changed) scale.x = f;
 
-					h = Id.handle();
+					h = Id.handle("tabobjects_11");
 					h.text = roundfp(scale.y) + "";
 					f = Std.parseFloat(ui.textInput(h, "Y"));
 					if (h.changed) scale.y = f;
 
-					h = Id.handle();
+					h = Id.handle("tabobjects_12");
 					h.text = roundfp(scale.z) + "";
 					f = Std.parseFloat(ui.textInput(h, "Z"));
 					if (h.changed) scale.z = f;
@@ -216,17 +216,17 @@ class TabObjects {
 					ui.row([1 / 4, 1 / 4, 1 / 4, 1 / 4]);
 					ui.text("Dimensions");
 
-					h = Id.handle();
+					h = Id.handle("tabobjects_13");
 					h.text = roundfp(dim.x) + "";
 					f = Std.parseFloat(ui.textInput(h, "X"));
 					if (h.changed) dim.x = f;
 
-					h = Id.handle();
+					h = Id.handle("tabobjects_14");
 					h.text = roundfp(dim.y) + "";
 					f = Std.parseFloat(ui.textInput(h, "Y"));
 					if (h.changed) dim.y = f;
 
-					h = Id.handle();
+					h = Id.handle("tabobjects_15");
 					h.text = roundfp(dim.z) + "";
 					f = Std.parseFloat(ui.textInput(h, "Z"));
 					if (h.changed) dim.z = f;
@@ -235,17 +235,17 @@ class TabObjects {
 
 					if (Context.raw.selectedObject.name == "Scene") {
 						var p = iron.Scene.active.world.probe;
-						p.raw.strength = ui.slider(Id.handle({value: p.raw.strength}), "Environment", 0.0, 5.0, true);
+						p.raw.strength = ui.slider(Id.handle("tabobjects_16", {value: p.raw.strength}), "Environment", 0.0, 5.0, true);
 					}
 					else if (Std.isOfType(Context.raw.selectedObject, iron.object.LightObject)) {
 						var light = cast(Context.raw.selectedObject, iron.object.LightObject);
-						var lightHandle = Id.handle();
+						var lightHandle = Id.handle("tabobjects_17");
 						lightHandle.value = light.data.raw.strength / 10;
 						light.data.raw.strength = ui.slider(lightHandle, "Strength", 0.0, 5.0, true) * 10;
 					}
 					else if (Std.isOfType(Context.raw.selectedObject, iron.object.CameraObject)) {
 						var cam = cast(Context.raw.selectedObject, iron.object.CameraObject);
-						var fovHandle = Id.handle();
+						var fovHandle = Id.handle("tabobjects_18");
 						fovHandle.value = Std.int(cam.data.raw.fov * 100) / 100;
 						cam.data.raw.fov = ui.slider(fovHandle, "FoV", 0.3, 2.0, true);
 						if (fovHandle.changed) {

+ 2 - 2
armorlab/Sources/arm/logic/InpaintNode.hx

@@ -49,8 +49,8 @@ class InpaintNode extends LogicNode {
 	public static function buttons(ui: zui.Zui, nodes: zui.Nodes, node: zui.Nodes.TNode) {
 		auto = node.buttons[0].default_value;
 		if (!auto) {
-			strength = ui.slider(zui.Id.handle({value: strength}), tr("strength"), 0, 1, true);
-			prompt = zui.Ext.textArea(ui, zui.Id.handle(), true, tr("prompt"), true);
+			strength = ui.slider(zui.Id.handle("inpaintnode_0", {value: strength}), tr("strength"), 0, 1, true);
+			prompt = zui.Ext.textArea(ui, zui.Id.handle("inpaintnode_1"), true, tr("prompt"), true);
 			node.buttons[1].height = 1 + prompt.split("\n").length;
 		}
 		else node.buttons[1].height = 0;

+ 1 - 1
armorlab/Sources/arm/logic/TextToPhotoNode.hx

@@ -32,7 +32,7 @@ class TextToPhotoNode extends LogicNode {
 
 	public static function buttons(ui: zui.Zui, nodes: zui.Nodes, node: zui.Nodes.TNode) {
 		tiling = node.buttons[0].default_value;
-		prompt = zui.Ext.textArea(ui, zui.Id.handle(), true, tr("prompt"), true);
+		prompt = zui.Ext.textArea(ui, zui.Id.handle("texttophotonode_0"), true, tr("prompt"), true);
 		node.buttons[1].height = prompt.split("\n").length;
 	}
 

+ 2 - 2
armorlab/Sources/arm/logic/TilingNode.hx

@@ -29,8 +29,8 @@ class TilingNode extends LogicNode {
 	public static function buttons(ui: zui.Zui, nodes: zui.Nodes, node: zui.Nodes.TNode) {
 		auto = node.buttons[0].default_value;
 		if (!auto) {
-			strength = ui.slider(zui.Id.handle({value: strength}), tr("strength"), 0, 1, true);
-			prompt = zui.Ext.textArea(ui, zui.Id.handle(), true, tr("prompt"), true);
+			strength = ui.slider(zui.Id.handle("tilingnode_0", {value: strength}), tr("strength"), 0, 1, true);
+			prompt = zui.Ext.textArea(ui, zui.Id.handle("tilingnode_1"), true, tr("prompt"), true);
 			node.buttons[1].height = 1 + prompt.split("\n").length;
 		}
 		else node.buttons[1].height = 0;

+ 1 - 1
armorlab/Sources/arm/logic/VarianceNode.hx

@@ -28,7 +28,7 @@ class VarianceNode extends LogicNode {
 	}
 
 	public static function buttons(ui: zui.Zui, nodes: zui.Nodes, node: zui.Nodes.TNode) {
-		prompt = zui.Ext.textArea(ui, zui.Id.handle(), true, tr("prompt"), true);
+		prompt = zui.Ext.textArea(ui, zui.Id.handle("variancenode_0"), true, tr("prompt"), true);
 		node.buttons[0].height = prompt.split("\n").length;
 	}
 

+ 21 - 21
armorpaint/Sources/arm/ui/TabLayers.hx

@@ -17,7 +17,7 @@ import arm.sys.Path;
 class TabLayers {
 
 	static var layerNameEdit = -1;
-	static var layerNameHandle = Id.handle();
+	static var layerNameHandle = new Handle();
 	static var showContextMenu = false;
 
 	public static function draw(htab: Handle) {
@@ -175,7 +175,7 @@ class TabLayers {
 		for (p in Project.paintObjects) ar.push(p.name);
 		var atlases = Project.getUsedAtlases();
 		if (atlases != null) for (a in atlases) ar.push(a);
-		var filterHandle = Id.handle();
+		var filterHandle = Id.handle("tablayers_0");
 		filterHandle.position = Context.raw.layerFilter;
 		Context.raw.layerFilter = ui.combo(filterHandle, ar, tr("Filter"), false, Left);
 		if (filterHandle.changed) {
@@ -439,7 +439,7 @@ class TabLayers {
 
 		if (hasPanel) {
 			ui._y += center;
-			var layerPanel = Id.handle().nest(l.id);
+			var layerPanel = Id.handle("tablayers_1").nest(l.id);
 			layerPanel.selected = l.show_panel;
 			l.show_panel = ui.panel(layerPanel, "", true, false, false);
 			ui._y -= center;
@@ -473,7 +473,7 @@ class TabLayers {
 		for (p in Project.paintObjects) ar.push(p.name);
 		var atlases = Project.getUsedAtlases();
 		if (atlases != null) for (a in atlases) ar.push(a);
-		var objectHandle = Id.handle().nest(l.id);
+		var objectHandle = Id.handle("tablayers_2").nest(l.id);
 		objectHandle.position = l.objectMask;
 		l.objectMask = ui.combo(objectHandle, ar, tr("Object"), label, Left);
 		if (objectHandle.changed) {
@@ -495,7 +495,7 @@ class TabLayers {
 	}
 
 	static function comboBlending(ui: Zui, l: LayerSlot, label = false): Handle {
-		var blendingHandle = Id.handle().nest(l.id);
+		var blendingHandle = Id.handle("tablayers_3").nest(l.id);
 		blendingHandle.position = l.blending;
 		ui.combo(blendingHandle, [
 			tr("Mix"),
@@ -704,7 +704,7 @@ class TabLayers {
 		UIMenu.draw(function(ui: Zui) {
 
 			if (mini) {
-				var visibleHandle = Id.handle();
+				var visibleHandle = Id.handle("tablayers_4");
 				visibleHandle.selected = l.visible;
 				UIMenu.menuFill(ui);
 				ui.check(visibleHandle, tr("Visible"));
@@ -839,7 +839,7 @@ class TabLayers {
 
 			UIMenu.menuFill(ui);
 			UIMenu.menuAlign(ui);
-			var layerOpacHandle = Id.handle().nest(l.id);
+			var layerOpacHandle = Id.handle("tablayers_5").nest(l.id);
 			layerOpacHandle.value = l.maskOpacity;
 			ui.slider(layerOpacHandle, tr("Opacity"), 0.0, 1.0, true);
 			if (layerOpacHandle.changed) {
@@ -887,7 +887,7 @@ class TabLayers {
 			if (l.fill_layer != null) {
 				UIMenu.menuFill(ui);
 				UIMenu.menuAlign(ui);
-				var scaleHandle = Id.handle().nest(l.id);
+				var scaleHandle = Id.handle("tablayers_6").nest(l.id);
 				scaleHandle.value = l.scale;
 				l.scale = ui.slider(scaleHandle, tr("UV Scale"), 0.0, 5.0, true);
 				if (scaleHandle.changed) {
@@ -902,7 +902,7 @@ class TabLayers {
 
 				UIMenu.menuFill(ui);
 				UIMenu.menuAlign(ui);
-				var angleHandle = Id.handle().nest(l.id);
+				var angleHandle = Id.handle("tablayers_7").nest(l.id);
 				angleHandle.value = l.angle;
 				l.angle = ui.slider(angleHandle, tr("Angle"), 0.0, 360, true, 1);
 				if (angleHandle.changed) {
@@ -918,7 +918,7 @@ class TabLayers {
 
 				UIMenu.menuFill(ui);
 				UIMenu.menuAlign(ui);
-				var uvTypeHandle = Id.handle().nest(l.id);
+				var uvTypeHandle = Id.handle("tablayers_8").nest(l.id);
 				uvTypeHandle.position = l.uvType;
 				l.uvType = zui.Ext.inlineRadio(ui, uvTypeHandle, [tr("UV Map"), tr("Triplanar"), tr("Project")], Left);
 				if (uvTypeHandle.changed) {
@@ -934,17 +934,17 @@ class TabLayers {
 			}
 
 			if (!l.isGroup()) {
-				var baseHandle = Id.handle().nest(l.id);
-				var opacHandle = Id.handle().nest(l.id);
-				var norHandle = Id.handle().nest(l.id);
-				var norBlendHandle = Id.handle().nest(l.id);
-				var occHandle = Id.handle().nest(l.id);
-				var roughHandle = Id.handle().nest(l.id);
-				var metHandle = Id.handle().nest(l.id);
-				var heightHandle = Id.handle().nest(l.id);
-				var heightBlendHandle = Id.handle().nest(l.id);
-				var emisHandle = Id.handle().nest(l.id);
-				var subsHandle = Id.handle().nest(l.id);
+				var baseHandle = Id.handle("tablayers_9").nest(l.id);
+				var opacHandle = Id.handle("tablayers_10").nest(l.id);
+				var norHandle = Id.handle("tablayers_11").nest(l.id);
+				var norBlendHandle = Id.handle("tablayers_12").nest(l.id);
+				var occHandle = Id.handle("tablayers_13").nest(l.id);
+				var roughHandle = Id.handle("tablayers_14").nest(l.id);
+				var metHandle = Id.handle("tablayers_15").nest(l.id);
+				var heightHandle = Id.handle("tablayers_16").nest(l.id);
+				var heightBlendHandle = Id.handle("tablayers_17").nest(l.id);
+				var emisHandle = Id.handle("tablayers_18").nest(l.id);
+				var subsHandle = Id.handle("tablayers_19").nest(l.id);
 				baseHandle.selected = l.paintBase;
 				opacHandle.selected = l.paintOpac;
 				norHandle.selected = l.paintNor;

+ 4 - 4
armorsculpt/Sources/arm/ui/TabLayers.hx

@@ -17,7 +17,7 @@ import arm.sys.Path;
 class TabLayers {
 
 	static var layerNameEdit = -1;
-	static var layerNameHandle = Id.handle();
+	static var layerNameHandle = new Handle();
 	static var showContextMenu = false;
 
 	public static function draw(htab: Handle) {
@@ -100,7 +100,7 @@ class TabLayers {
 	static function comboFilter() {
 		var ui = UIBase.inst.ui;
 		var ar = [tr("All")];
-		var filterHandle = Id.handle();
+		var filterHandle = Id.handle("tablayers_0");
 		filterHandle.position = Context.raw.layerFilter;
 		Context.raw.layerFilter = ui.combo(filterHandle, ar, tr("Filter"), false, Left);
 	}
@@ -320,7 +320,7 @@ class TabLayers {
 
 		if (hasPanel) {
 			ui._y += center;
-			var layerPanel = Id.handle().nest(l.id);
+			var layerPanel = Id.handle("tablayers_1").nest(l.id);
 			layerPanel.selected = l.show_panel;
 			l.show_panel = ui.panel(layerPanel, "", true, false, false);
 			ui._y -= center;
@@ -354,7 +354,7 @@ class TabLayers {
 
 	static function comboObject(ui: Zui, l: LayerSlot, label = false): Handle {
 		var ar = [tr("Shared")];
-		var objectHandle = Id.handle().nest(l.id);
+		var objectHandle = Id.handle("tablayers_2").nest(l.id);
 		objectHandle.position = l.objectMask;
 		l.objectMask = ui.combo(objectHandle, ar, tr("Object"), label, Left);
 		return objectHandle;

+ 2 - 2
base/Sources/arm/Config.hx

@@ -149,7 +149,7 @@ class Config {
 	}
 
 	public static function restore() {
-		zui.Zui.Handle.global = new zui.Zui.Handle(); // Reset ui handles
+		zui.Id.children = []; // Reset ui handles
 		configLoaded = false;
 		var _layout = raw.layout;
 		init();
@@ -166,7 +166,7 @@ class Config {
 		raw = from;
 		raw.sha = _sha;
 		raw.version = _version;
-		zui.Zui.Handle.global = new zui.Zui.Handle(); // Reset ui handles
+		zui.Id.children = []; // Reset ui handles
 		loadKeymap();
 		App.initLayout();
 		Translator.loadTranslations(raw.locale);

+ 1 - 1
base/Sources/arm/ContextFormat.hx

@@ -170,7 +170,7 @@ import arm.data.FontSlot;
 	@:optional public var drawTexels = false;
 	@:optional public var texelsHandle = new Handle({ selected: false });
 
-	@:optional public var colorIdHandle = Id.handle();
+	@:optional public var colorIdHandle = new Handle();
 	@:optional public var layersExport = ExportVisible;
 
 	@:optional public var decalImage: Image = null;

+ 9 - 9
base/Sources/arm/Project.hx

@@ -125,7 +125,7 @@ class Project {
 	public static function projectNewBox() {
 		#if (is_paint || is_sculpt)
 		UIBox.showCustom(function(ui: Zui) {
-			if (ui.tab(Id.handle(), tr("New Project"))) {
+			if (ui.tab(Id.handle("project_0"), tr("New Project"))) {
 				if (meshList == null) {
 					meshList = File.readDirectory(Path.data() + Path.sep + "meshes");
 					for (i in 0...meshList.length) meshList[i] = meshList[i].substr(0, meshList[i].length - 4); // Trim .arm
@@ -135,8 +135,8 @@ class Project {
 				}
 
 				ui.row([0.5, 0.5]);
-				Context.raw.projectType = ui.combo(Id.handle({ position: Context.raw.projectType }), meshList, tr("Template"), true);
-				Context.raw.projectAspectRatio = ui.combo(Id.handle({ position: Context.raw.projectAspectRatio }), ["1:1", "2:1", "1:2"], tr("Aspect Ratio"), true);
+				Context.raw.projectType = ui.combo(Id.handle("project_1", { position: Context.raw.projectType }), meshList, tr("Template"), true);
+				Context.raw.projectAspectRatio = ui.combo(Id.handle("project_2", { position: Context.raw.projectAspectRatio }), ["1:1", "2:1", "1:2"], tr("Aspect Ratio"), true);
 
 				@:privateAccess ui.endElement();
 				ui.row([0.5, 0.5]);
@@ -423,10 +423,10 @@ class Project {
 
 		UIBox.showCustom(function(ui: Zui) {
 			var tabVertical = Config.raw.touch_ui;
-			if (ui.tab(Id.handle(), tr("Import Mesh"), tabVertical)) {
+			if (ui.tab(Id.handle("project_3"), tr("Import Mesh"), tabVertical)) {
 
 				if (path.toLowerCase().endsWith(".obj")) {
-					Context.raw.splitBy = ui.combo(Id.handle(), [
+					Context.raw.splitBy = ui.combo(Id.handle("project_4"), [
 						tr("Object"),
 						tr("Group"),
 						tr("Material"),
@@ -436,13 +436,13 @@ class Project {
 				}
 
 				if (path.toLowerCase().endsWith(".fbx")) {
-					Context.raw.parseTransform = ui.check(Id.handle({ selected: Context.raw.parseTransform }), tr("Parse Transforms"));
+					Context.raw.parseTransform = ui.check(Id.handle("project_5", { selected: Context.raw.parseTransform }), tr("Parse Transforms"));
 					if (ui.isHovered) ui.tooltip(tr("Load per-object transforms from .fbx"));
 				}
 
 				#if (is_paint || is_sculpt)
 				if (path.toLowerCase().endsWith(".fbx") || path.toLowerCase().endsWith(".blend")) {
-					Context.raw.parseVCols = ui.check(Id.handle({ selected: Context.raw.parseVCols }), tr("Parse Vertex Colors"));
+					Context.raw.parseVCols = ui.check(Id.handle("project_6", { selected: Context.raw.parseVCols }), tr("Parse Vertex Colors"));
 					if (ui.isHovered) ui.tooltip(tr("Import vertex color data"));
 				}
 				#end
@@ -489,7 +489,7 @@ class Project {
 	public static function unwrapMeshBox(mesh: Dynamic, done: Dynamic->Void, skipUI = false) {
 		UIBox.showCustom(function(ui: Zui) {
 			var tabVertical = Config.raw.touch_ui;
-			if (ui.tab(Id.handle(), tr("Unwrap Mesh"), tabVertical)) {
+			if (ui.tab(Id.handle("project_7"), tr("Unwrap Mesh"), tabVertical)) {
 
 				var unwrapPlugins = [];
 				if (BoxPreferences.filesPlugin == null) {
@@ -502,7 +502,7 @@ class Project {
 				}
 				unwrapPlugins.push("equirect");
 
-				var unwrapBy = ui.combo(Id.handle(), unwrapPlugins, tr("Plugin"), true);
+				var unwrapBy = ui.combo(Id.handle("project_8"), unwrapPlugins, tr("Plugin"), true);
 
 				ui.row([0.5, 0.5]);
 				if (ui.button(tr("Cancel"))) {

+ 2 - 2
base/Sources/arm/shader/NodesMaterial.hx

@@ -2790,7 +2790,7 @@ class NodesMaterial {
 	@:access(zui.Zui)
 	public static function vectorCurvesButton(ui: Zui, nodes: Nodes, node: TNode) {
 		var but = node.buttons[0];
-		var nhandle = Id.handle().nest(node.id);
+		var nhandle = Id.handle("nodesmaterial_0").nest(node.id);
 		ui.row([1 / 3, 1 / 3, 1 / 3]);
 		ui.radio(nhandle.nest(0).nest(1), 0, "X");
 		ui.radio(nhandle.nest(0).nest(1), 1, "Y");
@@ -2825,7 +2825,7 @@ class NodesMaterial {
 	@:access(zui.Zui)
 	public static function colorRampButton(ui: Zui, nodes: Nodes, node: TNode) {
 		var but = node.buttons[0];
-		var nhandle = Id.handle().nest(node.id);
+		var nhandle = Id.handle("nodesmaterial_1").nest(node.id);
 		var nx = ui._x;
 		var ny = ui._y;
 

+ 20 - 20
base/Sources/arm/ui/BoxExport.hx

@@ -15,12 +15,12 @@ import arm.sys.File;
 
 class BoxExport {
 
-	public static var htab = Id.handle();
+	public static var htab = new Handle();
 	public static var files: Array<String> = null;
-	static var exportMeshHandle = Id.handle();
+	static var exportMeshHandle = new Handle();
 
 	#if (is_paint || is_lab)
-	public static var hpreset = Id.handle();
+	public static var hpreset = new Handle();
 	public static var preset: TExportPreset = null;
 	static var channels = ["base_r", "base_g", "base_b", "height", "metal", "nor_r", "nor_g", "nor_g_directx", "nor_b", "occ", "opac", "rough", "smooth", "emis", "subs", "0.0", "1.0"];
 	static var colorSpaces = ["linear", "srgb"];
@@ -114,20 +114,20 @@ class BoxExport {
 
 			ui.row([0.5, 0.5]);
 			if (App.bitsHandle.position == Bits8) {
-				Context.raw.formatType = ui.combo(Id.handle({ position: Context.raw.formatType }), ["png", "jpg"], tr("Format"), true);
+				Context.raw.formatType = ui.combo(Id.handle("boxexport_0", { position: Context.raw.formatType }), ["png", "jpg"], tr("Format"), true);
 			}
 			else {
-				Context.raw.formatType = ui.combo(Id.handle({ position: Context.raw.formatType }), ["exr"], tr("Format"), true);
+				Context.raw.formatType = ui.combo(Id.handle("boxexport_1", { position: Context.raw.formatType }), ["exr"], tr("Format"), true);
 			}
 
 			ui.enabled = Context.raw.formatType == FormatJpg && App.bitsHandle.position == Bits8;
-			Context.raw.formatQuality = ui.slider(Id.handle({ value: Context.raw.formatQuality }), tr("Quality"), 0.0, 100.0, true, 1);
+			Context.raw.formatQuality = ui.slider(Id.handle("boxexport_2", { value: Context.raw.formatQuality }), tr("Quality"), 0.0, 100.0, true, 1);
 			ui.enabled = true;
 
 			#if is_paint
 			ui.row([0.5, 0.5]);
 			ui.enabled = !bakeMaterial;
-			var layersExportHandle = Id.handle();
+			var layersExportHandle = Id.handle("boxexport_3");
 			layersExportHandle.position = Context.raw.layersExport;
 			Context.raw.layersExport = ui.combo(layersExportHandle, [tr("Visible"), tr("Selected"), tr("Per Object"), tr("Per Udim Tile")], tr("Layers"), true);
 			ui.enabled = true;
@@ -136,7 +136,7 @@ class BoxExport {
 			ui.combo(hpreset, files, tr("Preset"), true);
 			if (hpreset.changed) preset = null;
 
-			var layersDestinationHandle = Id.handle();
+			var layersDestinationHandle = Id.handle("boxexport_4");
 			layersDestinationHandle.position = Context.raw.layersDestination;
 			Context.raw.layersDestination = ui.combo(layersDestinationHandle, [tr("Disk"), tr("Packed")], tr("Destination"), true);
 
@@ -201,9 +201,9 @@ class BoxExport {
 			if (ui.button(tr("New"))) {
 				UIBox.showCustom(function(ui: Zui) {
 					var tabVertical = Config.raw.touch_ui;
-					if (ui.tab(Id.handle(), tr("New Preset"), tabVertical)) {
+					if (ui.tab(Id.handle("boxexport_5"), tr("New Preset"), tabVertical)) {
 						ui.row([0.5, 0.5]);
-						var presetName = ui.textInput(Id.handle({ text: "new_preset" }), tr("Name"));
+						var presetName = ui.textInput(Id.handle("boxexport_6", { text: "new_preset" }), tr("Name"));
 						if (ui.button(tr("OK")) || ui.isReturnDown) {
 							newPreset(presetName);
 							fetchPresets();
@@ -317,7 +317,7 @@ class BoxExport {
 			for (i in 0...Project.paintObjects.length) {
 				ui.row([1 / 2, 1 / 2]);
 				ui.text(Project.paintObjects[i].name);
-				var hatlas = Id.handle().nest(i);
+				var hatlas = Id.handle("boxexport_7").nest(i);
 				hatlas.position = Project.atlasObjects[i];
 				Project.atlasObjects[i] = ui.combo(hatlas, Project.atlasNames, tr("Atlas"));
 			}
@@ -328,7 +328,7 @@ class BoxExport {
 	public static function showMesh() {
 		exportMeshHandle.position = Context.raw.exportMeshIndex;
 		UIBox.showCustom(function(ui: Zui) {
-			var htab = Id.handle();
+			var htab = Id.handle("boxexport_8");
 			tabExportMesh(ui, htab);
 		});
 	}
@@ -339,13 +339,13 @@ class BoxExport {
 
 			ui.row([1 / 2, 1 / 2]);
 
-			Context.raw.exportMeshFormat = ui.combo(Id.handle({ position: Context.raw.exportMeshFormat }), ["obj", "arm"], tr("Format"), true);
+			Context.raw.exportMeshFormat = ui.combo(Id.handle("boxexport_9", { position: Context.raw.exportMeshFormat }), ["obj", "arm"], tr("Format"), true);
 
 			var ar = [tr("All")];
 			for (p in Project.paintObjects) ar.push(p.name);
 			ui.combo(exportMeshHandle, ar, tr("Meshes"), true);
 
-			var applyDisplacement = ui.check(Id.handle(), tr("Apply Displacement"));
+			var applyDisplacement = ui.check(Id.handle("boxexport_10"), tr("Apply Displacement"));
 
 			var tris = 0;
 			var pos = exportMeshHandle.position;
@@ -389,11 +389,11 @@ class BoxExport {
 	#if (is_paint || is_sculpt)
 	public static function showMaterial() {
 		UIBox.showCustom(function(ui: Zui) {
-			var htab = Id.handle();
+			var htab = Id.handle("boxexport_11");
 			var tabVertical = Config.raw.touch_ui;
 			if (ui.tab(htab, tr("Export Material"), tabVertical)) {
-				var h1 = Id.handle();
-				var h2 = Id.handle();
+				var h1 = Id.handle("boxexport_12");
+				var h2 = Id.handle("boxexport_13");
 				h1.selected = Context.raw.packAssetsOnExport;
 				h2.selected = Context.raw.writeIconOnExport;
 				Context.raw.packAssetsOnExport = ui.check(h1, tr("Pack Assets"));
@@ -418,11 +418,11 @@ class BoxExport {
 
 	public static function showBrush() {
 		UIBox.showCustom(function(ui: Zui) {
-			var htab = Id.handle();
+			var htab = Id.handle("boxexport_14");
 			var tabVertical = Config.raw.touch_ui;
 			if (ui.tab(htab, tr("Export Brush"), tabVertical)) {
-				var h1 = Id.handle();
-				var h2 = Id.handle();
+				var h1 = Id.handle("boxexport_15");
+				var h2 = Id.handle("boxexport_16");
 				h1.selected = Context.raw.packAssetsOnExport;
 				h2.selected = Context.raw.writeIconOnExport;
 				Context.raw.packAssetsOnExport = ui.check(h1, tr("Pack Assets"));

+ 58 - 58
base/Sources/arm/ui/BoxPreferences.hx

@@ -17,7 +17,7 @@ import arm.data.LayerSlot;
 
 class BoxPreferences {
 
-	public static var htab = Id.handle();
+	public static var htab = new Handle();
 	public static var filesPlugin: Array<String> = null;
 	public static var filesKeymap: Array<String> = null;
 	public static var themeHandle: Handle;
@@ -36,7 +36,7 @@ class BoxPreferences {
 					locales = Translator.getSupportedLocales();
 				}
 
-				var localeHandle = Id.handle({ position: locales.indexOf(Config.raw.locale) });
+				var localeHandle = Id.handle("boxpreferences_0", { position: locales.indexOf(Config.raw.locale) });
 				ui.combo(localeHandle, locales, tr("Language"), true);
 				if (localeHandle.changed) {
 					var localeCode = locales[localeHandle.position];
@@ -45,7 +45,7 @@ class BoxPreferences {
 					UIBase.inst.tagUIRedraw();
 				}
 
-				var hscale = Id.handle({ value: Config.raw.window_scale });
+				var hscale = Id.handle("boxpreferences_1", { value: Config.raw.window_scale });
 				ui.slider(hscale, tr("UI Scale"), 1.0, 4.0, true, 10);
 				if (Context.raw.hscaleWasChanged && !ui.inputDown) {
 					Context.raw.hscaleWasChanged = false;
@@ -55,35 +55,35 @@ class BoxPreferences {
 				}
 				if (hscale.changed) Context.raw.hscaleWasChanged = true;
 
-				var hspeed = Id.handle({ value: Config.raw.camera_zoom_speed });
+				var hspeed = Id.handle("boxpreferences_2", { value: Config.raw.camera_zoom_speed });
 				Config.raw.camera_zoom_speed = ui.slider(hspeed, tr("Camera Zoom Speed"), 0.1, 4.0, true);
 
-				hspeed = Id.handle({ value: Config.raw.camera_rotation_speed });
+				hspeed = Id.handle("boxpreferences_3", { value: Config.raw.camera_rotation_speed });
 				Config.raw.camera_rotation_speed = ui.slider(hspeed, tr("Camera Rotation Speed"), 0.1, 4.0, true);
 
-				hspeed = Id.handle({ value: Config.raw.camera_pan_speed });
+				hspeed = Id.handle("boxpreferences_4", { value: Config.raw.camera_pan_speed });
 				Config.raw.camera_pan_speed = ui.slider(hspeed, tr("Camera Pan Speed"), 0.1, 4.0, true);
 
-				var zoomDirectionHandle = Id.handle({ position: Config.raw.zoom_direction });
+				var zoomDirectionHandle = Id.handle("boxpreferences_5", { position: Config.raw.zoom_direction });
 				ui.combo(zoomDirectionHandle, [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 (zoomDirectionHandle.changed) {
 					Config.raw.zoom_direction = zoomDirectionHandle.position;
 				}
 
-				Config.raw.wrap_mouse = ui.check(Id.handle({ selected: Config.raw.wrap_mouse }), tr("Wrap Mouse"));
+				Config.raw.wrap_mouse = ui.check(Id.handle("boxpreferences_6", { selected: Config.raw.wrap_mouse }), tr("Wrap Mouse"));
 				if (ui.isHovered) ui.tooltip(tr("Wrap mouse around view boundaries during camera control"));
 
-				Config.raw.node_preview = ui.check(Id.handle({ selected: Config.raw.node_preview }), tr("Show Node Preview"));
+				Config.raw.node_preview = ui.check(Id.handle("boxpreferences_7", { selected: Config.raw.node_preview }), tr("Show Node Preview"));
 
 				ui.changed = false;
-				Config.raw.show_asset_names = ui.check(Id.handle({ selected: Config.raw.show_asset_names }), tr("Show Asset Names"));
+				Config.raw.show_asset_names = ui.check(Id.handle("boxpreferences_8", { selected: Config.raw.show_asset_names }), tr("Show Asset Names"));
 				if (ui.changed) {
 					UIBase.inst.tagUIRedraw();
 				}
 
 				#if !(kha_android || kha_ios)
 				ui.changed = false;
-				Config.raw.touch_ui = ui.check(Id.handle({ selected: Config.raw.touch_ui }), tr("Touch UI"));
+				Config.raw.touch_ui = ui.check(Id.handle("boxpreferences_9", { selected: Config.raw.touch_ui }), tr("Touch UI"));
 				if (ui.changed) {
 					Zui.touchScroll = Zui.touchHold = Zui.touchTooltip = Config.raw.touch_ui;
 					Config.loadTheme(Config.raw.theme);
@@ -92,10 +92,10 @@ class BoxPreferences {
 				}
 				#end
 
-				Config.raw.splash_screen = ui.check(Id.handle({ selected: Config.raw.splash_screen }), tr("Splash Screen"));
+				Config.raw.splash_screen = ui.check(Id.handle("boxpreferences_10", { selected: Config.raw.splash_screen }), tr("Splash Screen"));
 
 				// ui.text("Node Editor");
-				// var gridSnap = ui.check(Id.handle({ selected: false }), "Grid Snap");
+				// var gridSnap = ui.check(Id.handle("boxpreferences_11", { selected: false }), "Grid Snap");
 
 				ui.endElement();
 				ui.row([0.5, 0.5]);
@@ -144,7 +144,7 @@ class BoxPreferences {
 				if (themes == null) {
 					fetchThemes();
 				}
-				themeHandle = Id.handle({ position: getThemeIndex() });
+				themeHandle = Id.handle("boxpreferences_12", { position: getThemeIndex() });
 
 				ui.beginSticky();
 				ui.row([1 / 4, 1 / 4, 1 / 4, 1 / 4]);
@@ -157,9 +157,9 @@ class BoxPreferences {
 
 				if (ui.button(tr("New"))) {
 					UIBox.showCustom(function(ui: Zui) {
-						if (ui.tab(Id.handle(), tr("New Theme"))) {
+						if (ui.tab(Id.handle("boxpreferences_13"), tr("New Theme"))) {
 							ui.row([0.5, 0.5]);
-							var themeName = ui.textInput(Id.handle({ text: "new_theme" }), tr("Name"));
+							var themeName = ui.textInput(Id.handle("boxpreferences_14", { text: "new_theme" }), tr("Name"));
 							if (ui.button(tr("OK")) || ui.isReturnDown) {
 								var template = Json.stringify(arm.App.theme);
 								if (!themeName.endsWith(".json")) themeName += ".json";
@@ -194,7 +194,7 @@ class BoxPreferences {
 
 				var i = 0;
 				var theme = arm.App.theme;
-				var hlist = Id.handle();
+				var hlist = Id.handle("boxpreferences_15");
 
 				// Viewport color
 				var h = hlist.nest(i++, { color: worldColor });
@@ -276,7 +276,7 @@ class BoxPreferences {
 			}
 
 			if (ui.tab(htab, tr("Usage"), true)) {
-				Context.raw.undoHandle = Id.handle({ value: Config.raw.undo_steps });
+				Context.raw.undoHandle = Id.handle("boxpreferences_16", { value: Config.raw.undo_steps });
 				Config.raw.undo_steps = Std.int(ui.slider(Context.raw.undoHandle, tr("Undo Steps"), 1, 64, false, 1));
 				if (Config.raw.undo_steps < 1) {
 					Config.raw.undo_steps = Std.int(Context.raw.undoHandle.value = 1);
@@ -300,10 +300,10 @@ class BoxPreferences {
 				}
 
 				#if is_paint
-				Config.raw.dilate_radius = Std.int(ui.slider(Id.handle({ value: Config.raw.dilate_radius }), tr("Dilate Radius"), 0.0, 16.0, true, 1));
+				Config.raw.dilate_radius = Std.int(ui.slider(Id.handle("boxpreferences_17", { value: Config.raw.dilate_radius }), tr("Dilate Radius"), 0.0, 16.0, true, 1));
 				if (ui.isHovered) ui.tooltip(tr("Dilate painted textures to prevent seams"));
 
-				var dilateHandle = Id.handle({ position: Config.raw.dilate });
+				var dilateHandle = Id.handle("boxpreferences_18", { position: Config.raw.dilate });
 				ui.combo(dilateHandle, [tr("Instant"), tr("Delayed")], tr("Dilate"), true);
 				if (dilateHandle.changed) {
 					Config.raw.dilate = dilateHandle.position;
@@ -311,20 +311,20 @@ class BoxPreferences {
 				#end
 
 				#if is_lab
-				var workspaceHandle = Id.handle({ position: Config.raw.workspace });
+				var workspaceHandle = Id.handle("boxpreferences_19", { position: Config.raw.workspace });
 				ui.combo(workspaceHandle, [tr("3D View"), tr("2D View")], tr("Default Workspace"), true);
 				if (workspaceHandle.changed) {
 					Config.raw.workspace = workspaceHandle.position;
 				}
 				#end
 
-				var cameraControlsHandle = Id.handle({ position: Config.raw.camera_controls });
+				var cameraControlsHandle = Id.handle("boxpreferences_20", { position: Config.raw.camera_controls });
 				ui.combo(cameraControlsHandle, [tr("Orbit"), tr("Rotate"), tr("Fly")], tr("Default Camera Controls"), true);
 				if (cameraControlsHandle.changed) {
 					Config.raw.camera_controls = cameraControlsHandle.position;
 				}
 
-				var layerResHandle = Id.handle({ position: Config.raw.layer_res });
+				var layerResHandle = Id.handle("boxpreferences_21", { position: Config.raw.layer_res });
 
 				#if is_paint
 				#if (krom_android || krom_ios)
@@ -346,36 +346,36 @@ class BoxPreferences {
 					Config.raw.layer_res = layerResHandle.position;
 				}
 
-				var serverHandle = Id.handle({ text: Config.raw.server });
+				var serverHandle = Id.handle("boxpreferences_22", { text: Config.raw.server });
 				Config.raw.server = ui.textInput(serverHandle, tr("Cloud Server"));
 
 				#if (is_paint || is_sculpt)
-				var materialLiveHandle = Id.handle( {selected: Config.raw.material_live });
+				var materialLiveHandle = Id.handle("boxpreferences_23", {selected: Config.raw.material_live });
 				Config.raw.material_live = ui.check(materialLiveHandle, tr("Live Material Preview"));
 				if (ui.isHovered) ui.tooltip(tr("Instantly update material preview on node change"));
 
-				var brushLiveHandle = Id.handle({ selected: Config.raw.brush_live });
+				var brushLiveHandle = Id.handle("boxpreferences_24", { selected: Config.raw.brush_live });
 				Config.raw.brush_live = ui.check(brushLiveHandle, tr("Live Brush Preview"));
 				if (ui.isHovered) ui.tooltip(tr("Draw live brush preview in viewport"));
 				if (brushLiveHandle.changed) Context.raw.ddirty = 2;
 
-				var brush3dHandle = Id.handle({ selected: Config.raw.brush_3d });
+				var brush3dHandle = Id.handle("boxpreferences_25", { selected: Config.raw.brush_3d });
 				Config.raw.brush_3d = ui.check(brush3dHandle, tr("3D Cursor"));
 				if (brush3dHandle.changed) MakeMaterial.parsePaintMaterial();
 
 				ui.enabled = Config.raw.brush_3d;
-				var brushDepthRejectHandle = Id.handle({ selected: Config.raw.brush_depth_reject });
+				var brushDepthRejectHandle = Id.handle("boxpreferences_26", { selected: Config.raw.brush_depth_reject });
 				Config.raw.brush_depth_reject = ui.check(brushDepthRejectHandle, tr("Depth Reject"));
 				if (brushDepthRejectHandle.changed) MakeMaterial.parsePaintMaterial();
 
 				ui.row([0.5, 0.5]);
 
-				var brushAngleRejectHandle = Id.handle({ selected: Config.raw.brush_angle_reject });
+				var brushAngleRejectHandle = Id.handle("boxpreferences_27", { selected: Config.raw.brush_angle_reject });
 				Config.raw.brush_angle_reject = ui.check(brushAngleRejectHandle, tr("Angle Reject"));
 				if (brushAngleRejectHandle.changed) MakeMaterial.parsePaintMaterial();
 
 				if (!Config.raw.brush_angle_reject) ui.enabled = false;
-				var angleDotHandle = Id.handle({ value: Context.raw.brushAngleRejectDot });
+				var angleDotHandle = Id.handle("boxpreferences_28", { value: Context.raw.brushAngleRejectDot });
 				Context.raw.brushAngleRejectDot = ui.slider(angleDotHandle, tr("Angle"), 0.0, 1.0, true);
 				if (angleDotHandle.changed) {
 					MakeMaterial.parsePaintMaterial();
@@ -384,7 +384,7 @@ class BoxPreferences {
 				#end
 
 				#if is_lab
-				Config.raw.gpu_inference = ui.check(Id.handle({ selected: Config.raw.gpu_inference }), tr("Use GPU"));
+				Config.raw.gpu_inference = ui.check(Id.handle("boxpreferences_29", { selected: Config.raw.gpu_inference }), tr("Use GPU"));
 				if (ui.isHovered) ui.tooltip(tr("Use GPU to accelerate node graph processing"));
 				#end
 			}
@@ -395,12 +395,12 @@ class BoxPreferences {
 			if (ui.tab(htab, tr("Pen"), true)) {
 			#end
 				ui.text(tr("Pressure controls"));
-				Config.raw.pressure_radius = ui.check(Id.handle({ selected: Config.raw.pressure_radius }), tr("Brush Radius"));
-				Config.raw.pressure_sensitivity = ui.slider(Id.handle({ value: Config.raw.pressure_sensitivity }), tr("Sensitivity"), 0.0, 10.0, true);
+				Config.raw.pressure_radius = ui.check(Id.handle("boxpreferences_30", { selected: Config.raw.pressure_radius }), tr("Brush Radius"));
+				Config.raw.pressure_sensitivity = ui.slider(Id.handle("boxpreferences_31", { value: Config.raw.pressure_sensitivity }), tr("Sensitivity"), 0.0, 10.0, true);
 				#if (is_paint || is_sculpt)
-				Config.raw.pressure_hardness = ui.check(Id.handle({ selected: Config.raw.pressure_hardness }), tr("Brush Hardness"));
-				Config.raw.pressure_opacity = ui.check(Id.handle({ selected: Config.raw.pressure_opacity }), tr("Brush Opacity"));
-				Config.raw.pressure_angle = ui.check(Id.handle({ selected: Config.raw.pressure_angle }), tr("Brush Angle"));
+				Config.raw.pressure_hardness = ui.check(Id.handle("boxpreferences_32", { selected: Config.raw.pressure_hardness }), tr("Brush Hardness"));
+				Config.raw.pressure_opacity = ui.check(Id.handle("boxpreferences_33", { selected: Config.raw.pressure_opacity }), tr("Brush Opacity"));
+				Config.raw.pressure_angle = ui.check(Id.handle("boxpreferences_34", { selected: Config.raw.pressure_angle }), tr("Brush Angle"));
 				#end
 
 				ui.endElement();
@@ -415,15 +415,15 @@ class BoxPreferences {
 				}
 			}
 
-			Context.raw.hssao = Id.handle({ selected: Config.raw.rp_ssao });
-			Context.raw.hssr = Id.handle({ selected: Config.raw.rp_ssr });
-			Context.raw.hbloom = Id.handle({ selected: Config.raw.rp_bloom });
-			Context.raw.hsupersample = Id.handle({ position: Config.getSuperSampleQuality(Config.raw.rp_supersample) });
-			Context.raw.hvxao = Id.handle({ selected: Config.raw.rp_gi });
+			Context.raw.hssao = Id.handle("boxpreferences_35", { selected: Config.raw.rp_ssao });
+			Context.raw.hssr = Id.handle("boxpreferences_36", { selected: Config.raw.rp_ssr });
+			Context.raw.hbloom = Id.handle("boxpreferences_37", { selected: Config.raw.rp_bloom });
+			Context.raw.hsupersample = Id.handle("boxpreferences_38", { position: Config.getSuperSampleQuality(Config.raw.rp_supersample) });
+			Context.raw.hvxao = Id.handle("boxpreferences_39", { selected: Config.raw.rp_gi });
 			if (ui.tab(htab, tr("Viewport"), true)) {
 				#if (kha_direct3d12 || kha_vulkan || kha_metal)
 
-				var hpathtracemode = Id.handle({ position: Context.raw.pathTraceMode });
+				var hpathtracemode = Id.handle("boxpreferences_40", { position: Context.raw.pathTraceMode });
 				Context.raw.pathTraceMode = ui.combo(hpathtracemode, [tr("Core"), tr("Full")], tr("Path Tracer"), true);
 				if (hpathtracemode.changed) {
 					arm.render.RenderPathRaytrace.ready = false;
@@ -431,7 +431,7 @@ class BoxPreferences {
 
 				#end
 
-				var hrendermode = Id.handle({ position: Context.raw.renderMode });
+				var hrendermode = Id.handle("boxpreferences_41", { position: Context.raw.renderMode });
 				Context.raw.renderMode = ui.combo(hrendermode, [tr("Full"), tr("Mobile")], tr("Renderer"), true);
 				if (hrendermode.changed) {
 					Context.setRenderPath();
@@ -449,10 +449,10 @@ class BoxPreferences {
 					}
 
 					ui.enabled = Context.raw.hvxao.selected;
-					var h = Id.handle({ value: Context.raw.vxaoOffset });
+					var h = Id.handle("boxpreferences_42", { value: Context.raw.vxaoOffset });
 					Context.raw.vxaoOffset = ui.slider(h, tr("Cone Offset"), 1.0, 4.0, true);
 					if (h.changed) Context.raw.ddirty = 2;
-					var h = Id.handle({ value: Context.raw.vxaoAperture });
+					var h = Id.handle("boxpreferences_43", { value: Context.raw.vxaoAperture });
 					Context.raw.vxaoAperture = ui.slider(h, tr("Aperture"), 1.0, 4.0, true);
 					if (h.changed) Context.raw.ddirty = 2;
 					ui.enabled = true;
@@ -466,22 +466,22 @@ class BoxPreferences {
 					if (Context.raw.hbloom.changed) Config.applyConfig();
 				}
 
-				var h = Id.handle({ value: Config.raw.rp_vignette });
+				var h = Id.handle("boxpreferences_44", { value: Config.raw.rp_vignette });
 				Config.raw.rp_vignette = ui.slider(h, tr("Vignette"), 0.0, 1.0, true);
 				if (h.changed) Context.raw.ddirty = 2;
 
-				var h = Id.handle({ value: Config.raw.rp_grain });
+				var h = Id.handle("boxpreferences_45", { value: Config.raw.rp_grain });
 				Config.raw.rp_grain = ui.slider(h, tr("Noise Grain"), 0.0, 1.0, true);
 				if (h.changed) Context.raw.ddirty = 2;
 
-				// var h = Id.handle({ value: Context.raw.autoExposureStrength });
+				// var h = Id.handle("boxpreferences_46", { value: Context.raw.autoExposureStrength });
 				// Context.raw.autoExposureStrength = ui.slider(h, "Auto Exposure", 0.0, 2.0, true);
 				// if (h.changed) Context.raw.ddirty = 2;
 
 				var cam = iron.Scene.active.camera;
 				var camRaw = cam.data.raw;
-				var near_handle = Id.handle();
-				var far_handle = Id.handle();
+				var near_handle = Id.handle("boxpreferences_47");
+				var far_handle = Id.handle("boxpreferences_48");
 				near_handle.value = Std.int(camRaw.near_plane * 1000) / 1000;
 				far_handle.value = Std.int(camRaw.far_plane * 100) / 100;
 				camRaw.near_plane = ui.slider(near_handle, tr("Clip Start"), 0.001, 1.0, true);
@@ -490,7 +490,7 @@ class BoxPreferences {
 					cam.buildProjection();
 				}
 
-				var dispHandle = Id.handle({ value: Config.raw.displace_strength });
+				var dispHandle = Id.handle("boxpreferences_49", { value: Config.raw.displace_strength });
 				Config.raw.displace_strength = ui.slider(dispHandle, tr("Displacement Strength"), 0.0, 10.0, true);
 				if (dispHandle.changed) {
 					Context.raw.ddirty = 2;
@@ -506,7 +506,7 @@ class BoxPreferences {
 				ui.beginSticky();
 				ui.row([1 / 4, 1 / 4, 1 / 4, 1 / 4]);
 
-				presetHandle = Id.handle({ position: getPresetIndex() });
+				presetHandle = Id.handle("boxpreferences_50", { position: getPresetIndex() });
 				ui.combo(presetHandle, filesKeymap, tr("Preset"));
 				if (presetHandle.changed) {
 					Config.raw.keymap = filesKeymap[presetHandle.position] + ".json";
@@ -516,9 +516,9 @@ class BoxPreferences {
 
 				if (ui.button(tr("New"))) {
 					UIBox.showCustom(function(ui: Zui) {
-						if (ui.tab(Id.handle(), tr("New Keymap"))) {
+						if (ui.tab(Id.handle("boxpreferences_51"), tr("New Keymap"))) {
 							ui.row([0.5, 0.5]);
-							var keymapName = ui.textInput(Id.handle({ text: "new_keymap" }), tr("Name"));
+							var keymapName = ui.textInput(Id.handle("boxpreferences_52", { text: "new_keymap" }), tr("Name"));
 							if (ui.button(tr("OK")) || ui.isReturnDown) {
 								var template = Json.stringify(arm.App.defaultKeymap);
 								if (!keymapName.endsWith(".json")) keymapName += ".json";
@@ -555,7 +555,7 @@ class BoxPreferences {
 				var i = 0;
 				ui.changed = false;
 				for (key in Reflect.fields(Config.keymap)) {
-					var h = Id.handle().nest(i++);
+					var h = Id.handle("boxpreferences_53").nest(i++);
 					h.text = Reflect.field(Config.keymap, key);
 					var text = ui.textInput(h, key, Left);
 					Reflect.setField(Config.keymap, key, text);
@@ -570,9 +570,9 @@ class BoxPreferences {
 				ui.row([1 / 4, 1 / 4]);
 				if (ui.button(tr("New"))) {
 					UIBox.showCustom(function(ui: Zui) {
-						if (ui.tab(Id.handle(), tr("New Plugin"))) {
+						if (ui.tab(Id.handle("boxpreferences_54"), tr("New Plugin"))) {
 							ui.row([0.5, 0.5]);
-							var pluginName = ui.textInput(Id.handle({ text: "new_plugin" }), tr("Name"));
+							var pluginName = ui.textInput(Id.handle("boxpreferences_55", { text: "new_plugin" }), tr("Name"));
 							if (ui.button(tr("OK")) || ui.isReturnDown) {
 								var template =
 "let plugin = new arm.Plugin();
@@ -608,7 +608,7 @@ plugin.drawUI = function(ui) {
 				}
 
 				if (Config.raw.plugins == null) Config.raw.plugins = [];
-				var h = Id.handle({ selected: false });
+				var h = Id.handle("boxpreferences_56", { selected: false });
 				for (f in filesPlugin) {
 					var isJs = f.endsWith(".js");
 					var isWasm = false; //f.endsWith(".wasm");

+ 1 - 1
base/Sources/arm/ui/BoxProjects.hx

@@ -9,7 +9,7 @@ import arm.sys.File;
 @:access(zui.Zui)
 class BoxProjects {
 
-	public static var htab = Id.handle();
+	public static var htab = new Handle();
 	static var hsearch = new Handle();
 	static var iconMap: Map<String, kha.Image> = null;
 

+ 9 - 9
base/Sources/arm/ui/TabMaterials.hx

@@ -197,15 +197,15 @@ class TabMaterials {
 							deleteMaterial(m);
 						}
 
-						var baseHandle = Id.handle().nest(m.id, {selected: m.paintBase});
-						var opacHandle = Id.handle().nest(m.id, {selected: m.paintOpac});
-						var norHandle = Id.handle().nest(m.id, {selected: m.paintNor});
-						var occHandle = Id.handle().nest(m.id, {selected: m.paintOcc});
-						var roughHandle = Id.handle().nest(m.id, {selected: m.paintRough});
-						var metHandle = Id.handle().nest(m.id, {selected: m.paintMet});
-						var heightHandle = Id.handle().nest(m.id, {selected: m.paintHeight});
-						var emisHandle = Id.handle().nest(m.id, {selected: m.paintEmis});
-						var subsHandle = Id.handle().nest(m.id, {selected: m.paintSubs});
+						var baseHandle = Id.handle("tabmaterials_0").nest(m.id, {selected: m.paintBase});
+						var opacHandle = Id.handle("tabmaterials_1").nest(m.id, {selected: m.paintOpac});
+						var norHandle = Id.handle("tabmaterials_2").nest(m.id, {selected: m.paintNor});
+						var occHandle = Id.handle("tabmaterials_3").nest(m.id, {selected: m.paintOcc});
+						var roughHandle = Id.handle("tabmaterials_4").nest(m.id, {selected: m.paintRough});
+						var metHandle = Id.handle("tabmaterials_5").nest(m.id, {selected: m.paintMet});
+						var heightHandle = Id.handle("tabmaterials_6").nest(m.id, {selected: m.paintHeight});
+						var emisHandle = Id.handle("tabmaterials_7").nest(m.id, {selected: m.paintEmis});
+						var subsHandle = Id.handle("tabmaterials_8").nest(m.id, {selected: m.paintSubs});
 						UIMenu.menuFill(ui);
 						m.paintBase = ui.check(baseHandle, tr("Base Color"));
 						UIMenu.menuFill(ui);

+ 1 - 1
base/Sources/arm/ui/TabMeshes.hx

@@ -111,7 +111,7 @@ class TabMeshes {
 
 			for (i in 0...Project.paintObjects.length) {
 				var o = Project.paintObjects[i];
-				var h = Id.handle();
+				var h = Id.handle("tabmeshes_0");
 				h.selected = o.visible;
 				o.visible = ui.check(h, o.name);
 				if (ui.isHovered && ui.inputReleasedR) {

+ 1 - 1
base/Sources/arm/ui/TabScript.hx

@@ -10,7 +10,7 @@ import arm.sys.Path;
 
 class TabScript {
 
-	public static var hscript = Id.handle();
+	public static var hscript = new Handle();
 	static var textColoring: TTextColoring = null;
 
 	@:access(zui.Zui)

+ 6 - 6
base/Sources/arm/ui/TabSwatches.hx

@@ -126,7 +126,7 @@ class TabSwatches {
 						if (Time.time() - Context.raw.selectTime < 0.25) {
 							UIMenu.draw(function(ui) {
 								ui.changed = false;
-								var h = Id.handle();
+								var h = Id.handle("tabswatches_0");
 								h.color = Context.raw.swatch.base;
 
 								Context.raw.swatch.base = zui.Ext.colorWheel(ui, h, false, null, 11 * ui.t.ELEMENT_H * ui.SCALE(), true, function () {
@@ -136,19 +136,19 @@ class TabSwatches {
 										Project.raw.swatches[i] = Project.cloneSwatch(color);
 									};
 								});
-								var hopacity = Id.handle();
+								var hopacity = Id.handle("tabswatches_1");
 								hopacity.value = Context.raw.swatch.opacity;
 								Context.raw.swatch.opacity = ui.slider(hopacity, "Opacity", 0, 1, true);
-								var hocclusion = Id.handle();
+								var hocclusion = Id.handle("tabswatches_2");
 								hocclusion.value = Context.raw.swatch.occlusion;
 								Context.raw.swatch.occlusion = ui.slider(hocclusion, "Occlusion", 0, 1, true);
-								var hroughness = Id.handle();
+								var hroughness = Id.handle("tabswatches_3");
 								hroughness.value = Context.raw.swatch.roughness;
 								Context.raw.swatch.roughness = ui.slider(hroughness, "Roughness", 0, 1, true);
-								var hmetallic = Id.handle();
+								var hmetallic = Id.handle("tabswatches_4");
 								hmetallic.value = Context.raw.swatch.metallic;
 								Context.raw.swatch.metallic = ui.slider(hmetallic, "Metallic", 0, 1, true);
-								var hheight = Id.handle();
+								var hheight = Id.handle("tabswatches_5");
 								hheight.value = Context.raw.swatch.height;
 								Context.raw.swatch.height = ui.slider(hheight, "Height", 0, 1, true);
 

+ 11 - 11
base/Sources/arm/ui/UIBase.hx

@@ -46,8 +46,8 @@ class UIBase {
 	var redoTapTime = 0.0;
 
 	#if is_paint
-	public var hwnds = [Id.handle(), Id.handle(), Id.handle()];
-	public var htabs = [Id.handle(), Id.handle(), Id.handle()];
+	public var hwnds = [new Handle(), new Handle(), new Handle()];
+	public var htabs = [new Handle(), new Handle(), new Handle()];
 	public var hwndTabs = [
 		[TabLayers.draw, TabHistory.draw, TabPlugins.draw #if is_forge , TabObjects.draw #end],
 		[TabMaterials.draw, TabBrushes.draw, TabParticles.draw],
@@ -55,8 +55,8 @@ class UIBase {
 	];
 	#end
 	#if is_sculpt
-	public var hwnds = [Id.handle(), Id.handle(), Id.handle()];
-	public var htabs = [Id.handle(), Id.handle(), Id.handle()];
+	public var hwnds = [new Handle(), new Handle(), new Handle()];
+	public var htabs = [new Handle(), new Handle(), new Handle()];
 	public var hwndTabs = [
 		[TabLayers.draw, TabHistory.draw, TabPlugins.draw #if is_forge , TabObjects.draw #end],
 		[TabMaterials.draw, TabBrushes.draw, TabParticles.draw],
@@ -64,8 +64,8 @@ class UIBase {
 	];
 	#end
 	#if is_lab
-	public var hwnds = [Id.handle()];
-	public var htabs = [Id.handle()];
+	public var hwnds = [new Handle()];
+	public var htabs = [new Handle()];
 	public var hwndTabs = [
 		[TabBrowser.draw, TabTextures.draw, TabMeshes.draw, TabSwatches.draw, TabPlugins.draw, TabScript.draw, TabConsole.draw, UIStatus.drawVersionTab]
 	];
@@ -80,7 +80,7 @@ class UIBase {
 	public static inline var defaultSidebarW = defaultSidebarFullW;
 	#end
 	public var tabx = 0;
-	public var hminimized = Id.handle();
+	public var hminimized = new Handle();
 	public static var sidebarMiniW = defaultSidebarMiniW;
 	#end
 
@@ -510,7 +510,7 @@ class UIBase {
 				else if (Operator.shortcut(Config.keymap.view_zoom_out, ShortcutRepeat)) Viewport.zoom(-0.2);
 				else if (Operator.shortcut(Config.keymap.viewport_mode)) {
 					UIMenu.draw(function(ui: Zui) {
-						var modeHandle = Id.handle();
+						var modeHandle = Id.handle("uibase_0");
 						modeHandle.position = Context.raw.viewportMode;
 						ui.text(tr("Viewport Mode"), Right, ui.t.HIGHLIGHT_COL);
 						var modes = [
@@ -743,7 +743,7 @@ class UIBase {
 
 	function operatorSearch() {
 		var kb = Input.getKeyboard();
-		var searchHandle = Id.handle();
+		var searchHandle = Id.handle("uibase_1");
 		var first = true;
 		UIMenu.draw(function(ui: Zui) {
 			ui.fill(0, 0, ui._w / ui.SCALE(), ui.t.ELEMENT_H * 8, ui.t.SEPARATOR_COL);
@@ -1114,7 +1114,7 @@ class UIBase {
 			ui.inputEnabled = true;
 			g.end();
 			ui.begin(g);
-			if (ui.window(Id.handle(), 0, 0, 150, Std.int(ui.ELEMENT_H() + ui.ELEMENT_OFFSET() + 1))) {
+			if (ui.window(Id.handle("uibase_2"), 0, 0, 150, Std.int(ui.ELEMENT_H() + ui.ELEMENT_OFFSET() + 1))) {
 				if (ui.button(tr("Close"))) {
 					toggleDistractFree();
 				}
@@ -1182,7 +1182,7 @@ class UIBase {
 		if (Config.raw.touch_ui) {
 			var width = Config.raw.layout[LayoutSidebarW];
 			var height = Std.int(ui.ELEMENT_H() + ui.ELEMENT_OFFSET());
-			if (ui.window(Id.handle(), System.windowWidth() - width, System.windowHeight() - height, width, height + 1)) {
+			if (ui.window(Id.handle("uibase_3"), System.windowWidth() - width, System.windowHeight() - height, width, height + 1)) {
 				ui._w = width;
 				var _BUTTON_H = ui.t.BUTTON_H;
 				var _BUTTON_COL = ui.t.BUTTON_COL;

+ 2 - 2
base/Sources/arm/ui/UIBox.hx

@@ -75,8 +75,8 @@ class UIBox {
 			if (ui.window(hwnd, left, top, mw, mh, draggable)) {
 				ui._y += 10;
 				var tabVertical = Config.raw.touch_ui;
-				if (ui.tab(Id.handle(), boxTitle, tabVertical)) {
-					var htext = Id.handle();
+				if (ui.tab(Id.handle("uibox_0"), boxTitle, tabVertical)) {
+					var htext = Id.handle("uibox_1");
 					htext.text = boxText;
 					copyable ?
 						Ext.textArea(ui, htext, false) :

+ 25 - 25
base/Sources/arm/ui/UIHeader.hx

@@ -21,7 +21,7 @@ class UIHeader {
 	public static inline var defaultHeaderH = 28;
 	public static var headerh = defaultHeaderH;
 	public var headerHandle = new Handle({ layout: Horizontal });
-	public var worktab = Id.handle();
+	public var worktab = new Handle();
 
 	public function new() {
 		inst = this;
@@ -131,7 +131,7 @@ class UIHeader {
 			var heightPicked = Math.round(Context.raw.pickedColor.height * 100) / 100;
 			var opacityPicked = Math.round(Context.raw.pickedColor.opacity * 100) / 100;
 
-			var h = Id.handle();
+			var h = Id.handle("uiheader_0");
 			h.color.R = baseRPicked;
 			h.color.G = baseGPicked;
 			h.color.B = baseBPicked;
@@ -168,7 +168,7 @@ class UIHeader {
 			ui.text(tr("Metallic") + ' ($metallicPicked)');
 			ui.text(tr("Height") + ' ($heightPicked)');
 			ui.text(tr("Opacity") + ' ($opacityPicked)');
-			Context.raw.pickerSelectMaterial = ui.check(Id.handle({ selected: Context.raw.pickerSelectMaterial }), tr("Select Material"));
+			Context.raw.pickerSelectMaterial = ui.check(Id.handle("uiheader_1", { selected: Context.raw.pickerSelectMaterial }), tr("Select Material"));
 			ui.combo(Context.raw.pickerMaskHandle, [tr("None"), tr("Material")], tr("Mask"), true);
 			if (Context.raw.pickerMaskHandle.changed) {
 				MakeMaterial.parsePaintMaterial();
@@ -202,7 +202,7 @@ class UIHeader {
 				#end
 			}
 
-			var bakeHandle = Id.handle({ position: Context.raw.bakeType });
+			var bakeHandle = Id.handle("uiheader_2", { position: Context.raw.bakeType });
 			var bakes = [
 				tr("AO"),
 				tr("Curvature"),
@@ -237,25 +237,25 @@ class UIHeader {
 
 			#if (kha_direct3d12 || kha_vulkan || kha_metal)
 			if (rtBake) {
-				var samplesHandle = Id.handle({ value: Context.raw.bakeSamples });
+				var samplesHandle = Id.handle("uiheader_3", { value: Context.raw.bakeSamples });
 				Context.raw.bakeSamples = Std.int(ui.slider(samplesHandle, tr("Samples"), 1, 512, true, 1));
 			}
 			#end
 
 			if (Context.raw.bakeType == BakeNormalObject || Context.raw.bakeType == BakePosition || Context.raw.bakeType == BakeBentNormal) {
-				var bakeUpAxisHandle = Id.handle({ position: Context.raw.bakeUpAxis });
+				var bakeUpAxisHandle = Id.handle("uiheader_4", { position: Context.raw.bakeUpAxis });
 				Context.raw.bakeUpAxis = ui.combo(bakeUpAxisHandle, [tr("Z"), tr("Y")], tr("Up Axis"), true);
 			}
 			if (Context.raw.bakeType == BakeAO || Context.raw.bakeType == BakeCurvature) {
-				var bakeAxisHandle = Id.handle({ position: Context.raw.bakeAxis });
+				var bakeAxisHandle = Id.handle("uiheader_5", { position: Context.raw.bakeAxis });
 				Context.raw.bakeAxis = ui.combo(bakeAxisHandle, [tr("XYZ"), tr("X"), tr("Y"), tr("Z"), tr("-X"), tr("-Y"), tr("-Z")], tr("Axis"), true);
 			}
 			if (Context.raw.bakeType == BakeAO) {
-				var strengthHandle = Id.handle({ value: Context.raw.bakeAoStrength });
+				var strengthHandle = Id.handle("uiheader_6", { value: Context.raw.bakeAoStrength });
 				Context.raw.bakeAoStrength = ui.slider(strengthHandle, tr("Strength"), 0.0, 2.0, true);
-				var radiusHandle = Id.handle({ value: Context.raw.bakeAoRadius });
+				var radiusHandle = Id.handle("uiheader_7", { value: Context.raw.bakeAoRadius });
 				Context.raw.bakeAoRadius = ui.slider(radiusHandle, tr("Radius"), 0.0, 2.0, true);
-				var offsetHandle = Id.handle({ value: Context.raw.bakeAoOffset });
+				var offsetHandle = Id.handle("uiheader_8", { value: Context.raw.bakeAoOffset });
 				Context.raw.bakeAoOffset = ui.slider(offsetHandle, tr("Offset"), 0.0, 2.0, true);
 			}
 			#if (kha_direct3d12 || kha_vulkan || kha_metal)
@@ -274,18 +274,18 @@ class UIHeader {
 			}
 			#end
 			if (Context.raw.bakeType == BakeCurvature) {
-				var strengthHandle = Id.handle({ value: Context.raw.bakeCurvStrength });
+				var strengthHandle = Id.handle("uiheader_9", { value: Context.raw.bakeCurvStrength });
 				Context.raw.bakeCurvStrength = ui.slider(strengthHandle, tr("Strength"), 0.0, 2.0, true);
-				var radiusHandle = Id.handle({ value: Context.raw.bakeCurvRadius });
+				var radiusHandle = Id.handle("uiheader_10", { value: Context.raw.bakeCurvRadius });
 				Context.raw.bakeCurvRadius = ui.slider(radiusHandle, tr("Radius"), 0.0, 2.0, true);
-				var offsetHandle = Id.handle({ value: Context.raw.bakeCurvOffset });
+				var offsetHandle = Id.handle("uiheader_11", { value: Context.raw.bakeCurvOffset });
 				Context.raw.bakeCurvOffset = ui.slider(offsetHandle, tr("Offset"), -2.0, 2.0, true);
-				var smoothHandle = Id.handle({ value: Context.raw.bakeCurvSmooth });
+				var smoothHandle = Id.handle("uiheader_12", { value: Context.raw.bakeCurvSmooth });
 				Context.raw.bakeCurvSmooth = Std.int(ui.slider(smoothHandle, tr("Smooth"), 0, 5, false, 1));
 			}
 			if (Context.raw.bakeType == BakeNormal || Context.raw.bakeType == BakeHeight || Context.raw.bakeType == BakeDerivative) {
 				var ar = [for (p in Project.paintObjects) p.name];
-				var polyHandle = Id.handle({ position: Context.raw.bakeHighPoly });
+				var polyHandle = Id.handle("uiheader_13", { position: Context.raw.bakeHighPoly });
 				Context.raw.bakeHighPoly = ui.combo(polyHandle, ar, tr("High Poly"));
 			}
 			if (ui.changed) {
@@ -323,7 +323,7 @@ class UIHeader {
 				Context.raw.tool == ToolFill   ||
 				Context.raw.tool == ToolDecal  ||
 				Context.raw.tool == ToolText) {
-				var brushScaleHandle = Id.handle({ value: Context.raw.brushScale });
+				var brushScaleHandle = Id.handle("uiheader_14", { value: Context.raw.brushScale });
 				Context.raw.brushScale = ui.slider(brushScaleHandle, tr("UV Scale"), 0.01, 5.0, true);
 				if (brushScaleHandle.changed) {
 					if (Context.raw.tool == ToolDecal || Context.raw.tool == ToolText) {
@@ -345,11 +345,11 @@ class UIHeader {
 			if (ui.isHovered) ui.tooltip(tr("Hold {brush_opacity} and move mouse to the left to decrease the opacity\nHold {brush_opacity} and move mouse to the right to increase the opacity", ["brush_opacity" => Config.keymap.brush_opacity]));
 
 			if (Context.raw.tool == ToolBrush || Context.raw.tool == ToolEraser || Context.raw.tool == ToolClone || decalMask) {
-				Context.raw.brushHardness = ui.slider(Id.handle({ value: Context.raw.brushHardness }), tr("Hardness"), 0.0, 1.0, true);
+				Context.raw.brushHardness = ui.slider(Id.handle("uiheader_15", { value: Context.raw.brushHardness }), tr("Hardness"), 0.0, 1.0, true);
 			}
 
 			if (Context.raw.tool != ToolEraser) {
-				var brushBlendingHandle = Id.handle({ value: Context.raw.brushBlending });
+				var brushBlendingHandle = Id.handle("uiheader_16", { value: Context.raw.brushBlending });
 				Context.raw.brushBlending = ui.combo(brushBlendingHandle, [
 					tr("Mix"),
 					tr("Darken"),
@@ -376,14 +376,14 @@ class UIHeader {
 			}
 
 			if (Context.raw.tool == ToolBrush || Context.raw.tool == ToolFill) {
-				var paintHandle = Id.handle();
+				var paintHandle = Id.handle("uiheader_17");
 				Context.raw.brushPaint = ui.combo(paintHandle, [tr("UV Map"), tr("Triplanar"), tr("Project")], tr("TexCoord"));
 				if (paintHandle.changed) {
 					MakeMaterial.parsePaintMaterial();
 				}
 			}
 			if (Context.raw.tool == ToolText) {
-				var h = Id.handle();
+				var h = Id.handle("uiheader_18");
 				h.text = Context.raw.textToolText;
 				var w = ui._w;
 				if (ui.textSelectedHandle == h || ui.submitTextHandle == h) {
@@ -422,15 +422,15 @@ class UIHeader {
 				if (touchHeader) ui._x -= 4 * sc;
 				ui._w = Std.int((touchHeader ? 54 : 60) * sc);
 
-				var xrayHandle = Id.handle({ selected: Context.raw.xray });
+				var xrayHandle = Id.handle("uiheader_19", { selected: Context.raw.xray });
 				Context.raw.xray = ui.check(xrayHandle, tr("X-Ray"));
 				if (xrayHandle.changed) {
 					MakeMaterial.parsePaintMaterial();
 				}
 
-				var symXHandle = Id.handle({ selected: false });
-				var symYHandle = Id.handle({ selected: false });
-				var symZHandle = Id.handle({ selected: false });
+				var symXHandle = Id.handle("uiheader_20", { selected: false });
+				var symYHandle = Id.handle("uiheader_21", { selected: false });
+				var symZHandle = Id.handle("uiheader_22", { selected: false });
 
 				if (Config.raw.layout[LayoutHeader] == 1) {
 					if (Config.raw.touch_ui) {
@@ -470,7 +470,7 @@ class UIHeader {
 			#if arm_physics
 			if (Context.raw.tool == ToolParticle) {
 				ui._x += 10 * ui.SCALE();
-				var physHandle = Id.handle({ selected: false });
+				var physHandle = Id.handle("uiheader_23", { selected: false });
 				Context.raw.particlePhysics = ui.check(physHandle, tr("Physics"));
 				if (physHandle.changed) {
 					arm.util.ParticleUtil.initParticlePhysics();

+ 15 - 15
base/Sources/arm/ui/UIMenu.hx

@@ -141,14 +141,14 @@ class UIMenu {
 
 				menuFill(ui);
 				var p = Scene.active.world.probe;
-				var envHandle = Id.handle();
+				var envHandle = Id.handle("uimenu_0");
 				envHandle.value = p.raw.strength;
 				menuAlign(ui);
 				p.raw.strength = ui.slider(envHandle, tr("Environment"), 0.0, 8.0, true);
 				if (envHandle.changed) Context.raw.ddirty = 2;
 
 				menuFill(ui);
-				var envaHandle = Id.handle();
+				var envaHandle = Id.handle("uimenu_1");
 				envaHandle.value = Context.raw.envmapAngle / Math.PI * 180.0;
 				if (envaHandle.value < 0) {
 					envaHandle.value += (Std.int(-envaHandle.value / 360) + 1) * 360;
@@ -165,7 +165,7 @@ class UIMenu {
 					var light = Scene.active.lights[0];
 
 					menuFill(ui);
-					var lhandle = Id.handle();
+					var lhandle = Id.handle("uimenu_2");
 					var scale = 1333;
 					lhandle.value = light.data.raw.strength / scale;
 					lhandle.value = Std.int(lhandle.value * 100) / 100;
@@ -175,7 +175,7 @@ class UIMenu {
 
 					menuFill(ui);
 					var light = iron.Scene.active.lights[0];
-					var lahandle = Id.handle();
+					var lahandle = Id.handle("uimenu_3");
 					lahandle.value = Context.raw.lightAngle / Math.PI * 180;
 					menuAlign(ui);
 					var newAngle = ui.slider(lahandle, tr("Light Angle"), 0.0, 360.0, true, 1) / 180 * Math.PI;
@@ -193,7 +193,7 @@ class UIMenu {
 					}
 
 					menuFill(ui);
-					var sxhandle = Id.handle();
+					var sxhandle = Id.handle("uimenu_4");
 					sxhandle.value = light.data.raw.size;
 					menuAlign(ui);
 					light.data.raw.size = ui.slider(sxhandle, tr("Light Size"), 0.0, 4.0, true);
@@ -202,7 +202,7 @@ class UIMenu {
 
 				#if (is_paint || is_sculpt)
 				menuFill(ui);
-				var splitViewHandle = Id.handle({ selected: Context.raw.splitView });
+				var splitViewHandle = Id.handle("uimenu_5", { selected: Context.raw.splitView });
 				Context.raw.splitView = ui.check(splitViewHandle, " " + tr("Split View"));
 				if (splitViewHandle.changed) {
 					App.resize();
@@ -211,7 +211,7 @@ class UIMenu {
 
 				#if is_lab
 				menuFill(ui);
-				var brushScaleHandle = Id.handle({ value: Context.raw.brushScale });
+				var brushScaleHandle = Id.handle("uimenu_6", { value: Context.raw.brushScale });
 				menuAlign(ui);
 				Context.raw.brushScale = ui.slider(brushScaleHandle, tr("UV Scale"), 0.01, 5.0, true);
 				if (brushScaleHandle.changed) {
@@ -224,14 +224,14 @@ class UIMenu {
 				#end
 
 				menuFill(ui);
-				var cullHandle = Id.handle({ selected: Context.raw.cullBackfaces });
+				var cullHandle = Id.handle("uimenu_7", { selected: Context.raw.cullBackfaces });
 				Context.raw.cullBackfaces = ui.check(cullHandle, " " + tr("Cull Backfaces"));
 				if (cullHandle.changed) {
 					MakeMaterial.parseMeshMaterial();
 				}
 
 				menuFill(ui);
-				var filterHandle = Id.handle({ selected: Context.raw.textureFilter });
+				var filterHandle = Id.handle("uimenu_8", { selected: Context.raw.textureFilter });
 				Context.raw.textureFilter = ui.check(filterHandle, " " + tr("Filter Textures"));
 				if (filterHandle.changed) {
 					MakeMaterial.parsePaintMaterial();
@@ -258,7 +258,7 @@ class UIMenu {
 				#end
 
 				menuFill(ui);
-				var compassHandle = Id.handle({ selected: Context.raw.showCompass });
+				var compassHandle = Id.handle("uimenu_9", { selected: Context.raw.showCompass });
 				Context.raw.showCompass = ui.check(compassHandle, " " + tr("Compass"));
 				if (compassHandle.changed) Context.raw.ddirty = 2;
 
@@ -278,7 +278,7 @@ class UIMenu {
 				if (ui.changed) keepOpen = true;
 			}
 			else if (menuCategory == MenuMode) {
-				var modeHandle = Id.handle();
+				var modeHandle = Id.handle("uimenu_10");
 				modeHandle.position = Context.raw.viewportMode;
 				var modes = [
 					tr("Lit"),
@@ -380,7 +380,7 @@ class UIMenu {
 
 				menuFill(ui);
 				var cam = Scene.active.camera;
-				Context.raw.fovHandle = Id.handle({ value: Std.int(cam.data.raw.fov * 100) / 100 });
+				Context.raw.fovHandle = Id.handle("uimenu_11", { value: Std.int(cam.data.raw.fov * 100) / 100 });
 				menuAlign(ui);
 				cam.data.raw.fov = ui.slider(Context.raw.fovHandle, tr("FoV"), 0.3, 1.4, true);
 				if (Context.raw.fovHandle.changed) {
@@ -389,7 +389,7 @@ class UIMenu {
 
 				menuFill(ui);
 				menuAlign(ui);
-				var cameraControlsHandle = Id.handle();
+				var cameraControlsHandle = Id.handle("uimenu_12");
 				cameraControlsHandle.position = Context.raw.cameraControls;
 				Context.raw.cameraControls = Ext.inlineRadio(ui, cameraControlsHandle, [tr("Orbit"), tr("Rotate"), tr("Fly")], Left);
 
@@ -501,14 +501,14 @@ class UIMenu {
 
 					UIBox.showCustom(function(ui: Zui) {
 						var tabVertical = Config.raw.touch_ui;
-						if (ui.tab(Id.handle(), tr("About"), tabVertical)) {
+						if (ui.tab(Id.handle("uimenu_13"), tr("About"), tabVertical)) {
 
 							iron.data.Data.getImage("badge.k", function(img) {
 								ui.image(img);
 								ui.endElement();
 							});
 
-							Ext.textArea(ui, Id.handle({ text: msg }), false);
+							Ext.textArea(ui, Id.handle("uimenu_14", { text: msg }), false);
 
 							ui.row([1 / 3, 1 / 3, 1 / 3]);
 

+ 13 - 13
base/Sources/arm/ui/UINodes.hx

@@ -58,7 +58,7 @@ class UINodes {
 	var isNodeMenuOperation = false;
 
 	public var grid: Image = null;
-	public var hwnd = Id.handle();
+	public var hwnd = new Handle();
 	public var groupStack: Array<TNodeGroup> = [];
 	public var controlsDown = false;
 
@@ -143,14 +143,14 @@ class UINodes {
 				App.notifyOnNextFrame(function() {
 					UIMenu.draw(function(ui: Zui) {
 						if (UIMenu.menuButton(ui, tr("Edit"))) {
-							var htype = Id.handle();
-							var hname = Id.handle();
-							var hmin = Id.handle();
-							var hmax = Id.handle();
-							var hval0 = Id.handle();
-							var hval1 = Id.handle();
-							var hval2 = Id.handle();
-							var hval3 = Id.handle();
+							var htype = Id.handle("uinodes_0");
+							var hname = Id.handle("uinodes_1");
+							var hmin = Id.handle("uinodes_2");
+							var hmax = Id.handle("uinodes_3");
+							var hval0 = Id.handle("uinodes_4");
+							var hval1 = Id.handle("uinodes_5");
+							var hval2 = Id.handle("uinodes_6");
+							var hval3 = Id.handle("uinodes_7");
 							htype.position = socket.type == "RGBA" ? 0 : socket.type == "VECTOR" ? 1 : 2;
 							hname.text = socket.name;
 							hmin.value = socket.min;
@@ -167,7 +167,7 @@ class UINodes {
 							App.notifyOnNextFrame(function() {
 								App.uiBox.endInput();
 								UIBox.showCustom(function(ui: Zui) {
-									if (ui.tab(Id.handle(), tr("Socket"))) {
+									if (ui.tab(Id.handle("uinodes_8"), tr("Socket"))) {
 										var type = ui.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");
 										var name = ui.textInput(hname, tr("Name"));
@@ -532,7 +532,7 @@ class UINodes {
 
 	function nodeSearch(x = -1, y = -1, done: Void->Void = null) {
 		var kb = Input.getKeyboard();
-		var searchHandle = Id.handle();
+		var searchHandle = Id.handle("uinodes_9");
 		var first = true;
 		UIMenu.draw(function(ui: Zui) {
 			ui.g.color = ui.t.SEPARATOR_COL;
@@ -768,7 +768,7 @@ class UINodes {
 
 		if (ui.window(hwnd, wx, wy, ww, wh)) {
 
-			ui.tab(Id.handle(), tr("Nodes"));
+			ui.tab(Id.handle("uinodes_10"), tr("Nodes"));
 
 			// Grid
 			ui.g.color = 0xffffffff;
@@ -958,7 +958,7 @@ class UINodes {
 
 			#if (is_paint || is_sculpt)
 			// Editable canvas name
-			var h = Id.handle();
+			var h = Id.handle("uinodes_11");
 			h.text = c.name;
 			ui._w = Std.int(Math.min(ui.ops.font.width(ui.fontSize, h.text) + 15 * ui.SCALE(), 100 * ui.SCALE()));
 			var newName = ui.textInput(h, "");

+ 7 - 7
base/Sources/arm/ui/UIView2D.hx

@@ -40,7 +40,7 @@ class UIView2D {
 	public var ww: Int;
 	public var wh: Int;
 	public var ui: Zui;
-	public var hwnd = Id.handle();
+	public var hwnd = new Handle();
 	public var panX = 0.0;
 	public var panY = 0.0;
 	public var panScale = 1.0;
@@ -124,7 +124,7 @@ class UIView2D {
 
 		if (ui.window(hwnd, wx, wy, ww, wh)) {
 
-			ui.tab(Id.handle(), tr("2D View"));
+			ui.tab(Id.handle("uiview2d_0"), tr("2D View"));
 
 			// Grid
 			ui.g.color = 0xffffffff;
@@ -294,7 +294,7 @@ class UIView2D {
 			ui._w = ew;
 
 			// Editable layer name
-			var h = Id.handle();
+			var h = Id.handle("uiview2d_1");
 
 			#if (is_paint || is_sculpt)
 			var text = type == View2DNode ? Context.raw.nodePreviewName : h.text;
@@ -347,7 +347,7 @@ class UIView2D {
 
 			#if (is_paint || is_sculpt)
 			if (type == View2DLayer) {
-				layerMode = ui.combo(Id.handle({ position: layerMode }), [
+				layerMode = ui.combo(Id.handle("uiview2d_2", { position: layerMode }), [
 					tr("Visible"),
 					tr("Selected"),
 				], tr("Layers"));
@@ -355,7 +355,7 @@ class UIView2D {
 				ui._y = 2 + startY;
 
 				if (!Context.raw.layer.isMask()) {
-					texType = ui.combo(Id.handle({ position: texType }), [
+					texType = ui.combo(Id.handle("uiview2d_3", { position: texType }), [
 						tr("Base Color"),
 						tr("Normal Map"),
 						tr("Occlusion"),
@@ -369,13 +369,13 @@ class UIView2D {
 				}
 
 				ui._w = Std.int(ew * 0.7 + 3);
-				uvmapShow = ui.check(Id.handle({ selected: uvmapShow }), tr("UV Map"));
+				uvmapShow = ui.check(Id.handle("uiview2d_4", { selected: uvmapShow }), tr("UV Map"));
 				ui._x += ew * 0.7 + 3;
 				ui._y = 2 + startY;
 			}
 			#end
 
-			tiledShow = ui.check(Id.handle({ selected: tiledShow }), tr("Tiled"));
+			tiledShow = ui.check(Id.handle("uiview2d_5", { selected: tiledShow }), tr("Tiled"));
 			ui._x += ew * 0.7 + 3;
 			ui._y = 2 + startY;