luboslenco 1 year ago
parent
commit
6d8f98b8ff

+ 2 - 14
armorpaint/Sources/RenderPathPreview.ts

@@ -71,14 +71,8 @@ class RenderPathPreview {
 		render_path_set_target("mgbuffer2");
 		render_path_clear_target(0xff000000);
 
-		///if (krom_metal)
-		let clearColor = 0xffffffff;
-		///else
-		let clearColor: Null<i32> = null;
-		///end
-
 		render_path_set_target("mgbuffer0");
-		render_path_clear_target(clearColor, 1.0, clear_flag_t.COLOR | clear_flag_t.DEPTH);
+		render_path_clear_target(0xffffffff, 1.0, clear_flag_t.COLOR | clear_flag_t.DEPTH);
 		render_path_set_target("mgbuffer0", ["mgbuffer1", "mgbuffer2"]);
 		render_path_draw_meshes("mesh");
 
@@ -121,14 +115,8 @@ class RenderPathPreview {
 		render_path_set_target("gbuffer2");
 		render_path_clear_target(0xff000000);
 
-		///if (krom_metal)
-		let clearColor = 0xffffffff;
-		///else
-		let clearColor: Null<i32> = null;
-		///end
-
 		render_path_set_target("gbuffer0");
-		render_path_clear_target(clearColor, 1.0, clear_flag_t.COLOR | clear_flag_t.DEPTH);
+		render_path_clear_target(0xffffffff, 1.0, clear_flag_t.COLOR | clear_flag_t.DEPTH);
 		render_path_set_target("gbuffer0", ["gbuffer1", "gbuffer2"]);
 		render_path_draw_meshes("mesh");
 

+ 11 - 11
armorpaint/Sources/TabLayers.ts

@@ -162,7 +162,7 @@ class TabLayers {
 		if (atlases != null) for (let a of atlases) ar.push(a);
 		let filterHandle = zui_handle("tablayers_0");
 		filterHandle.position = Context.raw.layerFilter;
-		Context.raw.layerFilter = zui_combo(filterHandle, ar, tr("Filter"), false, Align.Left);
+		Context.raw.layerFilter = zui_combo(filterHandle, ar, tr("Filter"), false, zui_align_t.LEFT);
 		if (filterHandle.changed) {
 			for (let p of Project.paintObjects) {
 				p.base.visible = Context.raw.layerFilter == 0 || p.base.name == ar[Context.raw.layerFilter] || Project.isAtlasObject(p);
@@ -317,7 +317,7 @@ class TabLayers {
 		let parentHidden = l.parent != null && (!l.parent.visible || (l.parent.parent != null && !l.parent.parent.visible));
 		if (parentHidden) col -= 0x99000000;
 
-		if (zui_image(icons, col, null, r.x, r.y, r.w, r.h) == State.Released) {
+		if (zui_image(icons, col, -1.0, r.x, r.y, r.w, r.h) == zui_state_t.RELEASED) {
 			TabLayers.layerToggleVisible(l);
 		}
 		ui._x -= 2;
@@ -360,7 +360,7 @@ class TabLayers {
 			if (ui.text_selected_handle_ptr != TabLayers.layerNameHandle.ptr) TabLayers.layerNameEdit = -1;
 		}
 		else {
-			if (ui.enabled && ui.input_enabled && ui.combo_selected_handle_ptr == null &&
+			if (ui.enabled && ui.input_enabled && ui.combo_selected_handle_ptr == 0 &&
 				ui.input_x > ui._window_x + ui._x && ui.input_x < ui._window_x + ui._window_w &&
 				ui.input_y > ui._window_y + ui._y - center && ui.input_y < ui._window_y + ui._y - center + (step * zui_SCALE(ui)) * 2) {
 				if (ui.input_started) {
@@ -374,7 +374,7 @@ class TabLayers {
 			}
 
 			let state = zui_text(l.name);
-			if (state == State.Released) {
+			if (state == zui_state_t.RELEASED) {
 				if (time_time() - Context.raw.selectTime < 0.25) {
 					TabLayers.layerNameEdit = l.id;
 					TabLayers.layerNameHandle.text = l.name;
@@ -453,7 +453,7 @@ class TabLayers {
 		if (atlases != null) for (let a of atlases) ar.push(a);
 		let objectHandle = zui_nest(zui_handle("tablayers_2"), l.id);
 		objectHandle.position = l.objectMask;
-		l.objectMask = zui_combo(objectHandle, ar, tr("Object"), label, Align.Left);
+		l.objectMask = zui_combo(objectHandle, ar, tr("Object"), label, zui_align_t.LEFT);
 		if (objectHandle.changed) {
 			Context.setLayer(l);
 			MakeMaterial.parseMeshMaterial();
@@ -528,7 +528,7 @@ class TabLayers {
 		}
 	}
 
-	static handleLayerIconState = (l: SlotLayerRaw, i: i32, state: State, uix: f32, uiy: f32) => {
+	static handleLayerIconState = (l: SlotLayerRaw, i: i32, state: zui_state_t, uix: f32, uiy: f32) => {
 		let ui = UIBase.ui;
 
 		///if is_paint
@@ -559,11 +559,11 @@ class TabLayers {
 			TabLayers.showContextMenu = true;
 		}
 
-		if (state == State.Started) {
+		if (state == zui_state_t.STARTED) {
 			Context.setLayer(l);
 			TabLayers.setDragLayer(Context.raw.layer, -(mouse_x - uix - ui._window_x - 3), -(mouse_y - uiy - ui._window_y + 1));
 		}
-		else if (state == State.Released) {
+		else if (state == zui_state_t.RELEASED) {
 			if (time_time() - Context.raw.selectTime < 0.2) {
 				UIBase.show2DView(View2DType.View2DLayer);
 			}
@@ -837,7 +837,7 @@ class TabLayers {
 				///end
 				let _y = ui._y;
 				Base.resHandle.value = Base.resHandle.position;
-				Base.resHandle.position = Math.floor(zui_slider(Base.resHandle, ar[Base.resHandle.position], 0, ar.length - 1, false, 1, false, Align.Left, false));
+				Base.resHandle.position = Math.floor(zui_slider(Base.resHandle, ar[Base.resHandle.position], 0, ar.length - 1, false, 1, false, zui_align_t.LEFT, false));
 				if (Base.resHandle.changed) {
 					UIMenu.keepOpen = true;
 				}
@@ -845,7 +845,7 @@ class TabLayers {
 					Base.onLayersResized();
 				}
 				ui._y = _y;
-				zui_draw_string(tr("Res"), null, 0, Align.Right);
+				zui_draw_string(tr("Res"), null, 0, zui_align_t.RIGHT);
 				zui_end_element();
 
 				UIMenu.menuFill(ui);
@@ -897,7 +897,7 @@ class TabLayers {
 				UIMenu.menuAlign(ui);
 				let uvTypeHandle = zui_nest(zui_handle("tablayers_8"), l.id);
 				uvTypeHandle.position = l.uvType;
-				l.uvType = zui_inline_radio(uvTypeHandle, [tr("UV Map"), tr("Triplanar"), tr("Project")], Align.Left);
+				l.uvType = zui_inline_radio(uvTypeHandle, [tr("UV Map"), tr("Triplanar"), tr("Project")], zui_align_t.LEFT);
 				if (uvTypeHandle.changed) {
 					Context.setMaterial(l.fill_layer);
 					Context.setLayer(l);

+ 5 - 5
armorsculpt/Sources/TabLayers.ts

@@ -87,7 +87,7 @@ class TabLayers {
 		let ar = [tr("All")];
 		let filterHandle = zui_handle("tablayers_0");
 		filterHandle.position = Context.raw.layerFilter;
-		Context.raw.layerFilter = zui_combo(filterHandle, ar, tr("Filter"), false, Align.Left);
+		Context.raw.layerFilter = zui_combo(filterHandle, ar, tr("Filter"), false, zui_align_t.LEFT);
 	}
 
 	static remapLayerPointers = (nodes: zui_node_t[], pointerMap: Map<i32, i32>) => {
@@ -222,7 +222,7 @@ class TabLayers {
 		let parentHidden = l.parent != null && (!l.parent.visible || (l.parent.parent != null && !l.parent.parent.visible));
 		if (parentHidden) col -= 0x99000000;
 
-		if (zui_image(icons, col, null, r.x, r.y, r.w, r.h) == State.Released) {
+		if (zui_image(icons, col, -1.0, r.x, r.y, r.w, r.h) == zui_state_t.RELEASED) {
 			TabLayers.layerToggleVisible(l);
 		}
 		ui._x -= 2;
@@ -240,7 +240,7 @@ class TabLayers {
 			if (ui.text_selected_handle_ptr != TabLayers.layerNameHandle.ptr) TabLayers.layerNameEdit = -1;
 		}
 		else {
-			if (ui.enabled && ui.input_enabled && ui.combo_selected_handle_ptr == null &&
+			if (ui.enabled && ui.input_enabled && ui.combo_selected_handle_ptr == 0 &&
 				ui.input_x > ui._window_x + ui._x && ui.input_x < ui._window_x + ui._window_w &&
 				ui.input_y > ui._window_y + ui._y - center && ui.input_y < ui._window_y + ui._y - center + (step * zui_SCALE(ui)) * 2) {
 				if (ui.input_started) {
@@ -259,7 +259,7 @@ class TabLayers {
 			}
 
 			let state = zui_text(l.name);
-			if (state == State.Released) {
+			if (state == zui_state_t.RELEASED) {
 				let td = time_time() - Context.raw.selectTime;
 				if (td < 0.2 && td > 0.0) {
 					TabLayers.layerNameEdit = l.id;
@@ -339,7 +339,7 @@ class TabLayers {
 		let ar = [tr("Shared")];
 		let objectHandle = zui_nest(zui_handle("tablayers_2"), l.id);
 		objectHandle.position = l.objectMask;
-		l.objectMask = zui_combo(objectHandle, ar, tr("Object"), label, Align.Left);
+		l.objectMask = zui_combo(objectHandle, ar, tr("Object"), label, zui_align_t.LEFT);
 		return objectHandle;
 	}
 

+ 3 - 3
base/Sources/Base.ts

@@ -163,8 +163,8 @@ class Base {
 		Base.colorWheelGradient = imageColorWheelGradient;
 		zui_set_enum_texts(Base.enumTexts);
 		zui_tr = tr;
-		Base.uiBox = zui_create({ theme: Base.theme, font: f, scaleFactor: Config.raw.window_scale, color_wheel: Base.colorWheel, black_white_gradient: Base.colorWheelGradient });
-		Base.uiMenu = zui_create({ theme: Base.theme, font: f, scaleFactor: Config.raw.window_scale, color_wheel: Base.colorWheel, black_white_gradient: Base.colorWheelGradient });
+		Base.uiBox = zui_create({ theme: Base.theme, font: f, scale_factor: Config.raw.window_scale, color_wheel: Base.colorWheel, black_white_gradient: Base.colorWheelGradient });
+		Base.uiMenu = zui_create({ theme: Base.theme, font: f, scale_factor: Config.raw.window_scale, color_wheel: Base.colorWheel, black_white_gradient: Base.colorWheelGradient });
 		Base.defaultElementH = Base.uiMenu.t.ELEMENT_H;
 
 		// Init plugins
@@ -859,7 +859,7 @@ class Base {
 	}
 
 	static isComboSelected = (): bool => {
-		for (let ui of Base.getUIs()) if (ui.combo_selected_handle_ptr != null) return true;
+		for (let ui of Base.getUIs()) if (ui.combo_selected_handle_ptr != 0) return true;
 		return false;
 	}
 

+ 1 - 1
base/Sources/BoxPreferences.ts

@@ -549,7 +549,7 @@ class BoxPreferences {
 				for (let key in Config.keymap) {
 					let h = zui_nest(zui_handle("boxpreferences_53"), i++);
 					h.text = Config.keymap[key];
-					let text = zui_text_input(h, key, Align.Left);
+					let text = zui_text_input(h, key, zui_align_t.LEFT);
 					Config.keymap[key] = text;
 				}
 				if (ui.changed) {

+ 9 - 9
base/Sources/BoxProjects.ts

@@ -110,7 +110,7 @@ class BoxProjects {
 						zui_fill(0, 0, 128, 128, ui.t.SEPARATOR_COL);
 
 						let state = zui_image(icon, 0xffffffff, 128  * zui_SCALE(ui));
-						if (state == State.Released) {
+						if (state == zui_state_t.RELEASED) {
 							let _uix = ui._x;
 							ui._x = uix;
 							zui_fill(0, 0, 128, 128, 0x66000000);
@@ -151,7 +151,7 @@ class BoxProjects {
 						if (show_asset_names) {
 							ui._x = uix - (150 - 128) / 2;
 							ui._y += slotw * 0.9;
-							zui_text(name, Align.Center);
+							zui_text(name, zui_align_t.CENTER);
 							if (ui.is_hovered) zui_tooltip(name);
 							ui._y -= slotw * 0.9;
 							if (i == recent_projects.length - 1) {
@@ -177,21 +177,21 @@ class BoxProjects {
 			BoxProjects.drawBadge(ui);
 
 			ui.enabled = Config.raw.recent_projects.length > 0;
-			BoxProjects.hsearch.text = zui_text_input(BoxProjects.hsearch, tr("Search"), Align.Left, true, true);
+			BoxProjects.hsearch.text = zui_text_input(BoxProjects.hsearch, tr("Search"), zui_align_t.LEFT, true, true);
 			ui.enabled = true;
 
 			for (let path of Config.raw.recent_projects) {
 				let file = path;
 				///if krom_windows
-				file = path.replaceAll("/", "\\");
+				file = string_replace_all(path, "/", "\\");
 				///else
-				file = path.replaceAll("\\", "/");
+				file = string_replace_all(path, "\\", "/");
 				///end
 				file = file.substr(file.lastIndexOf(Path.sep) + 1);
 
 				if (file.toLowerCase().indexOf(BoxProjects.hsearch.text.toLowerCase()) < 0) continue; // Search filter
 
-				if (zui_button(file, Align.Left) && File.exists(path)) {
+				if (zui_button(file, zui_align_t.LEFT) && File.exists(path)) {
 					let current = _g2_current;
 					if (current != null) g2_end();
 
@@ -204,15 +204,15 @@ class BoxProjects {
 			}
 
 			ui.enabled = Config.raw.recent_projects.length > 0;
-			if (zui_button(tr("Clear"), Align.Left)) {
+			if (zui_button(tr("Clear"), zui_align_t.LEFT)) {
 				Config.raw.recent_projects = [];
 				Config.save();
 			}
 			ui.enabled = true;
 
 			zui_end_element();
-			if (zui_button(tr("New Project..."), Align.Left)) Project.projectNewBox();
-			if (zui_button(tr("Open..."), Align.Left)) Project.projectOpen();
+			if (zui_button(tr("New Project..."), zui_align_t.LEFT)) Project.projectNewBox();
+			if (zui_button(tr("Open..."), zui_align_t.LEFT)) Project.projectOpen();
 		}
 	}
 

+ 3 - 3
base/Sources/Config.ts

@@ -4,7 +4,7 @@ class Config {
 	static raw: TConfig = null;
 	static keymap: any;
 	static configLoaded = false;
-	static buttonAlign = Align.Left;
+	static buttonAlign = zui_align_t.LEFT;
 	static defaultButtonSpacing = "       ";
 	static buttonSpacing = Config.defaultButtonSpacing;
 
@@ -293,12 +293,12 @@ class Config {
 			Base.theme.ARROW_SIZE = 5 + 2;
 			Base.theme.CHECK_SIZE = 15 + 4;
 			Base.theme.CHECK_SELECT_SIZE = 8 + 2;
-			Config.buttonAlign = Align.Left;
+			Config.buttonAlign = zui_align_t.LEFT;
 			Config.buttonSpacing = "";
 		}
 		else {
 			Base.theme.FULL_TABS = false;
-			Config.buttonAlign = Align.Left;
+			Config.buttonAlign = zui_align_t.LEFT;
 			Config.buttonSpacing = Config.defaultButtonSpacing;
 		}
 	}

+ 2 - 2
base/Sources/ExportArm.ts

@@ -241,7 +241,7 @@ class ExportArm {
 
 		let texture_files = ExportArm.assetsToFiles(path, assets);
 		let isCloud = path.endsWith("_cloud_.arm");
-		if (isCloud) path = path.replaceAll("_cloud_", "");
+		if (isCloud) path = string_replace_all(path, "_cloud_", "");
 		let packed_assets: TPackedAsset[] = null;
 		if (!Context.raw.packAssetsOnExport) {
 			packed_assets = ExportArm.getPackedAssets(path, texture_files);
@@ -301,7 +301,7 @@ class ExportArm {
 
 		let texture_files = ExportArm.assetsToFiles(path, assets);
 		let isCloud = path.endsWith("_cloud_.arm");
-		if (isCloud) path = path.replaceAll("_cloud_", "");
+		if (isCloud) path = string_replace_all(path, "_cloud_", "");
 		let packed_assets: TPackedAsset[] = null;
 		if (!Context.raw.packAssetsOnExport) {
 			packed_assets = ExportArm.getPackedAssets(path, texture_files);

+ 4 - 4
base/Sources/File.ts

@@ -18,11 +18,11 @@ class File {
 
 	static readDirectory = (path: string, foldersOnly = false): string[] => {
 		if (path.startsWith("cloud")) {
-			let files = File.cloud != null ? File.cloud.get(path.replaceAll("\\", "/")) : null;
+			let files = File.cloud != null ? File.cloud.get(string_replace_all(path, "\\", "/")) : null;
 			return files != null ? files : [];
 		}
 		// ///if krom_android
-		// path = path.replaceAll("//", "/");
+		// path = string_replace_all(path, "//", "/");
 		// if (internal == null) {
 		// 	internal = [];
 		// 	internal.set("/data/plugins", BuildMacros.readDirectory("krom/data/plugins"));
@@ -96,7 +96,7 @@ class File {
 
 	static cacheCloud = (path: string, done: (s: string)=>void) => {
 		///if krom_ios
-		let path2 = path.replaceAll("/", "_"); // Cache everything into root folder
+		let path2 = string_replace_all(path, "/", "_"); // Cache everything into root folder
 		///else
 		let path2 = path;
 		///end
@@ -115,7 +115,7 @@ class File {
 			File.createDirectory(fileDir);
 		}
 		///if krom_windows
-		path = path.replaceAll("\\", "/");
+		path = string_replace_all(path, "\\", "/");
 		///end
 		let url = Config.raw.server + "/" + path;
 		File.download(url, dest, () => {

+ 10 - 10
base/Sources/ImportArm.ts

@@ -90,9 +90,9 @@ class ImportArm {
 
 		for (let file of project.assets) {
 			///if krom_windows
-			file = file.replaceAll("/", "\\");
+			file = string_replace_all(file, "/", "\\");
 			///else
-			file = file.replaceAll("\\", "/");
+			file = string_replace_all(file, "\\", "/");
 			///end
 			// Convert image path from relative to absolute
 			let abs = data_is_abs(file) ? file : base + file;
@@ -111,9 +111,9 @@ class ImportArm {
 		if (project.font_assets != null) {
 			for (let file of project.font_assets) {
 				///if krom_windows
-				file = file.replaceAll("/", "\\");
+				file = string_replace_all(file, "/", "\\");
 				///else
-				file = file.replaceAll("\\", "/");
+				file = string_replace_all(file, "\\", "/");
 				///end
 				// Convert font path from relative to absolute
 				let abs = data_is_abs(file) ? file : base + file;
@@ -392,9 +392,9 @@ class ImportArm {
 		let base = Path.baseDir(path);
 		for (let file of project.assets) {
 			///if krom_windows
-			file = file.replaceAll("/", "\\");
+			file = string_replace_all(file, "/", "\\");
 			///else
-			file = file.replaceAll("\\", "/");
+			file = string_replace_all(file, "\\", "/");
 			///end
 			// Convert image path from relative to absolute
 			let abs = data_is_abs(file) ? file : base + file;
@@ -474,9 +474,9 @@ class ImportArm {
 		let base = Path.baseDir(path);
 		for (let file of project.assets) {
 			///if krom_windows
-			file = file.replaceAll("/", "\\");
+			file = string_replace_all(file, "/", "\\");
 			///else
-			file = file.replaceAll("\\", "/");
+			file = string_replace_all(file, "\\", "/");
 			///end
 			// Convert image path from relative to absolute
 			let abs = data_is_abs(file) ? file : base + file;
@@ -571,9 +571,9 @@ class ImportArm {
 		}
 		for (let pa of project.packed_assets) {
 			///if krom_windows
-			pa.name = pa.name.replaceAll("/", "\\");
+			pa.name = string_replace_all(pa.name, "/", "\\");
 			///else
-			pa.name = pa.name.replaceAll("\\", "/");
+			pa.name = string_replace_all(pa.name, "\\", "/");
 			///end
 			pa.name = Path.normalize(pa.name);
 			if (pa.name == file) pa.name = abs; // From relative to absolute

+ 1 - 1
base/Sources/ImportBlendMaterial.ts

@@ -73,7 +73,7 @@ class ImportBlendMaterial {
 				for (let list of NodesMaterial.list) {
 					let found = false;
 					for (let n of list) {
-						let s = n.type.replaceAll("_", "").toLowerCase();
+						let s = string_replace_all(n.type, "_", "").toLowerCase();
 						if (search == s) {
 							base = n;
 							found = true;

+ 6 - 6
base/Sources/NodesMaterial.ts

@@ -2803,13 +2803,13 @@ class NodesMaterial {
 			if (val.length > 2) val.pop();
 		}
 		let ihandle = zui_nest(zui_nest(zui_nest(nhandle, 0), 2), axis, {position: 0});
-		let i = Math.floor(zui_slider(ihandle, "Index", 0, num - 1, false, 1, true, Align.Left));
+		let i = Math.floor(zui_slider(ihandle, "Index", 0, num - 1, false, 1, true, zui_align_t.LEFT));
 		if (i >= val.length || i < 0) ihandle.value = i = val.length - 1; // Stay in bounds
 		zui_row([1 / 2, 1 / 2]);
 		zui_nest(zui_nest(nhandle, 0), 3).value = val[i][0];
 		zui_nest(zui_nest(nhandle, 0), 4).value = val[i][1];
-		val[i][0] = zui_slider(zui_nest(zui_nest(nhandle, 0), 3, {value: 0}), "X", -1, 1, true, 100, true, Align.Left);
-		val[i][1] = zui_slider(zui_nest(zui_nest(nhandle, 0), 4, {value: 0}), "Y", -1, 1, true, 100, true, Align.Left);
+		val[i][0] = zui_slider(zui_nest(zui_nest(nhandle, 0), 3, {value: 0}), "X", -1, 1, true, 100, true, zui_align_t.LEFT);
+		val[i][1] = zui_slider(zui_nest(zui_nest(nhandle, 0), 4, {value: 0}), "Y", -1, 1, true, 100, true, zui_align_t.LEFT);
 	}
 
 	static colorRampButton = (ui: zui_t, nodes: zui_nodes_t, node: zui_node_t) => {
@@ -2848,18 +2848,18 @@ class NodesMaterial {
 		but.data = zui_combo(zui_nest(zui_nest(nhandle, 0), 1, {position: but.data}), [tr("Linear"), tr("Constant")], tr("Interpolate"));
 
 		zui_row([1 / 2, 1 / 2]);
-		let i = Math.floor(zui_slider(ihandle, "Index", 0, vals.length - 1, false, 1, true, Align.Left));
+		let i = Math.floor(zui_slider(ihandle, "Index", 0, vals.length - 1, false, 1, true, zui_align_t.LEFT));
 		if (i >= vals.length || i < 0) ihandle.value = i = vals.length - 1; // Stay in bounds
 
 		let val = vals[i];
 		zui_nest(zui_nest(nhandle, 0), 3).value = val[4];
-		val[4] = zui_slider(zui_nest(zui_nest(nhandle, 0), 3), "Pos", 0, 1, true, 100, true, Align.Left);
+		val[4] = zui_slider(zui_nest(zui_nest(nhandle, 0), 3), "Pos", 0, 1, true, 100, true, zui_align_t.LEFT);
 		if (val[4] > 1.0) val[4] = 1.0; // Stay in bounds
 		else if (val[4] < 0.0) val[4] = 0.0;
 
 		let chandle = zui_nest(zui_nest(nhandle, 0), 4);
 		chandle.color = color_from_floats(val[0], val[1], val[2], 1.0);
-		if (zui_text("", Align.Right, chandle.color) == State.Started) {
+		if (zui_text("", zui_align_t.RIGHT, chandle.color) == zui_state_t.STARTED) {
 			let rx = nx + ui._w - zui_nodes_p(37);
 			let ry = ny - zui_nodes_p(5);
 			nodes._inputStarted = ui.input_started = false;

+ 1 - 1
base/Sources/ParserLogic.ts

@@ -52,7 +52,7 @@ class ParserLogic {
 	}
 
 	static safe_src = (s: string): string => {
-		return s.replaceAll(" ", "");
+		return string_replace_all(s, " ", "");
 	}
 
 	static node_name = (node: zui_node_t): string => {

+ 12 - 12
base/Sources/ParserMaterial.ts

@@ -481,7 +481,7 @@ class ParserMaterial {
 			let co = ParserMaterial.getCoord(node);
 			let but = node.buttons[0]; //gradient_type;
 			let grad: string = but.data[but.default_value].toUpperCase();
-			grad = grad.replaceAll(" ", "_");
+			grad = string_replace_all(grad, " ", "_");
 			let f = ParserMaterial.getGradient(grad, co);
 			let res = ParserMaterial.to_vec3(`clamp(${f}, 0.0, 1.0)`);
 			return res;
@@ -526,7 +526,7 @@ class ParserMaterial {
 			let scale = ParserMaterial.parse_value_input(node.inputs[1]);
 			let but = node.buttons[0]; //coloring;
 			let coloring: string = but.data[but.default_value].toUpperCase();
-			coloring = coloring.replaceAll(" ", "_");
+			coloring = string_replace_all(coloring, " ", "_");
 			let res = "";
 			if (coloring == "INTENSITY") {
 				res = ParserMaterial.to_vec3(`tex_voronoi(${co} * ${scale}, texturePass(snoise256)).a`);
@@ -606,7 +606,7 @@ class ParserMaterial {
 			let col2 = ParserMaterial.parse_vector_input(node.inputs[2]);
 			let but = node.buttons[0]; // blend_type
 			let blend: string = but.data[but.default_value].toUpperCase();
-			blend = blend.replaceAll(" ", "_");
+			blend = string_replace_all(blend, " ", "_");
 			let use_clamp = node.buttons[1].default_value == true;
 			let out_col = "";
 			if (blend == "MIX") {
@@ -959,7 +959,7 @@ class ParserMaterial {
 			let nm2 = ParserMaterial.parse_vector_input(node.inputs[1]);
 			let but = node.buttons[0];
 			let blend: string = but.data[but.default_value].toUpperCase(); // blend_type
-			blend = blend.replaceAll(" ", "_");
+			blend = string_replace_all(blend, " ", "_");
 			let store = ParserMaterial.store_var_name(node);
 
 			// The blending algorithms are based on the paper `Blending in Detail` by Colin Barré-Brisebois and Stephen Hill 2012
@@ -998,7 +998,7 @@ class ParserMaterial {
 			let vec2 = ParserMaterial.parse_vector_input(node.inputs[1]);
 			let but = node.buttons[0]; //operation;
 			let op: string = but.data[but.default_value].toUpperCase();
-			op = op.replaceAll(" ", "_");
+			op = string_replace_all(op, " ", "_");
 			if (op == "ADD") {
 				return `(${vec1} + ${vec2})`;
 			}
@@ -1328,7 +1328,7 @@ class ParserMaterial {
 			let co = ParserMaterial.getCoord(node);
 			let but = node.buttons[0]; //gradient_type;
 			let grad: string = but.data[but.default_value].toUpperCase();
-			grad = grad.replaceAll(" ", "_");
+			grad = string_replace_all(grad, " ", "_");
 			let f = ParserMaterial.getGradient(grad, co);
 			let res = `(clamp(${f}, 0.0, 1.0))`;
 			return res;
@@ -1375,7 +1375,7 @@ class ParserMaterial {
 			let scale = ParserMaterial.parse_value_input(node.inputs[1]);
 			let but = node.buttons[0]; // coloring
 			let coloring: string = but.data[but.default_value].toUpperCase();
-			coloring = coloring.replaceAll(" ", "_");
+			coloring = string_replace_all(coloring, " ", "_");
 			let res = "";
 			if (coloring == "INTENSITY") {
 				res = `tex_voronoi(${co} * ${scale}, texturePass(snoise256)).a`;
@@ -1422,7 +1422,7 @@ class ParserMaterial {
 			let val2 = ParserMaterial.parse_value_input(node.inputs[1]);
 			let but = node.buttons[0]; // operation
 			let op: string = but.data[but.default_value].toUpperCase();
-			op = op.replaceAll(" ", "_");
+			op = string_replace_all(op, " ", "_");
 			let use_clamp = node.buttons[1].default_value == true;
 			let out_val = "";
 			if (op == "ADD") {
@@ -1596,7 +1596,7 @@ class ParserMaterial {
 			let vec2 = ParserMaterial.parse_vector_input(node.inputs[1]);
 			let but = node.buttons[0]; //operation;
 			let op: string = but.data[but.default_value].toUpperCase();
-			op = op.replaceAll(" ", "_");
+			op = string_replace_all(op, " ", "_");
 			if (op == "DOT_PRODUCT") {
 				return `dot(${vec1}, ${vec2})`;
 			}
@@ -1616,7 +1616,7 @@ class ParserMaterial {
 			let max = ParserMaterial.parse_value_input(node.inputs[2]);
 			let but = node.buttons[0]; //operation;
 			let op: string = but.data[but.default_value].toUpperCase();
-			op = op.replaceAll(" ", "_");
+			op = string_replace_all(op, " ", "_");
 
 			if (op == "MIN_MAX") {
 				return `(clamp(${val}, ${min}, ${max}))`;
@@ -1855,11 +1855,11 @@ class ParserMaterial {
 			let code = s.charCodeAt(i);
 			let letter = (code >= 65 && code <= 90) || (code >= 97 && code <= 122);
 			let digit = code >= 48 && code <= 57;
-			if (!letter && !digit) s = s.replaceAll(s.charAt(i), "_");
+			if (!letter && !digit) s = string_replace_all(s, s.charAt(i), "_");
 			if (i == 0 && digit) s = "_" + s;
 		}
 		///if krom_opengl
-		while (s.indexOf("__") >= 0) s = s.replaceAll("__", "_");
+		while (s.indexOf("__") >= 0) s = string_replace_all(s, "__", "_");
 		///end
 		return s;
 	}

+ 2 - 2
base/Sources/Path.ts

@@ -127,7 +127,7 @@ class Path {
 	}
 
 	static checkExt = (p: string, exts: string[]): bool => {
-		p = p.replaceAll("-", "_");
+		p = string_replace_all(p, "-", "_");
 		for (let ext of exts) {
 			if (p.endsWith("_" + ext) ||
 				(p.indexOf("_" + ext + "_") >= 0 && !p.endsWith("_preview") && !p.endsWith("_icon"))) {
@@ -160,7 +160,7 @@ class Path {
 	}
 
 	static isFolder = (p: string): bool => {
-		return p.replaceAll("\\", "/").split("/").pop().indexOf(".") == -1;
+		return string_replace_all(p, "\\", "/").split("/").pop().indexOf(".") == -1;
 	}
 
 	static isProtected = (): bool => {

+ 4 - 4
base/Sources/TabBrowser.ts

@@ -65,7 +65,7 @@ class TabBrowser {
 			if (zui_button(tr("Refresh")) || (inFocus && ui.is_key_pressed && ui.key == key_code_t.F5)) {
 				refresh = true;
 			}
-			TabBrowser.hsearch.text = zui_text_input(TabBrowser.hsearch, tr("Search"), Align.Left, true, true);
+			TabBrowser.hsearch.text = zui_text_input(TabBrowser.hsearch, tr("Search"), zui_align_t.LEFT, true, true);
 			if (ui.is_hovered) zui_tooltip(tr("ctrl+f to search") + "\n" + tr("esc to cancel"));
 			if (ui.is_ctrl_down && ui.is_key_pressed && ui.key == key_code_t.F) { // Start searching via ctrl+f
 				zui_start_text_edit(TabBrowser.hsearch);
@@ -176,11 +176,11 @@ class TabBrowser {
 			ui._y = _y;
 			ui._w = bookmarksW;
 
-			if (zui_button(tr("Cloud"), Align.Left)) {
+			if (zui_button(tr("Cloud"), zui_align_t.LEFT)) {
 				TabBrowser.hpath.text = "cloud";
 			}
 
-			if (zui_button(tr("Disk"), Align.Left)) {
+			if (zui_button(tr("Disk"), zui_align_t.LEFT)) {
 				///if krom_android
 				UIMenu.draw((ui: zui_t) => {
 					if (UIMenu.menuButton(ui, tr("Download"))) {
@@ -204,7 +204,7 @@ class TabBrowser {
 			for (let b of Config.raw.bookmarks) {
 				let folder = b.substr(b.lastIndexOf(Path.sep) + 1);
 
-				if (zui_button(folder, Align.Left)) {
+				if (zui_button(folder, zui_align_t.LEFT)) {
 					TabBrowser.hpath.text = b;
 				}
 

+ 3 - 3
base/Sources/TabBrushes.ts

@@ -61,8 +61,8 @@ class TabBrushes {
 					let uix = ui._x;
 					//let uiy = ui._y;
 					let tile = zui_SCALE(ui) > 1 ? 100 : 50;
-					let state = Project.brushes[i].previewReady ? zui_image(img) : zui_image(Res.get("icons.k"), -1, null, tile * 5, tile, tile, tile);
-					if (state == State.Started) {
+					let state = Project.brushes[i].previewReady ? zui_image(img) : zui_image(Res.get("icons.k"), -1, -1.0, tile * 5, tile, tile, tile);
+					if (state == zui_state_t.STARTED) {
 						if (Context.raw.brush != Project.brushes[i]) Context.selectBrush(i);
 						if (time_time() - Context.raw.selectTime < 0.25) UIBase.showBrushNodes();
 						Context.raw.selectTime = time_time();
@@ -118,7 +118,7 @@ class TabBrushes {
 					if (Config.raw.show_asset_names) {
 						ui._x = uix;
 						ui._y += slotw * 0.9;
-						zui_text(Project.brushes[i].canvas.name, Align.Center);
+						zui_text(Project.brushes[i].canvas.name, zui_align_t.CENTER);
 						if (ui.is_hovered) zui_tooltip(Project.brushes[i].canvas.name);
 						ui._y -= slotw * 0.9;
 						if (i == Project.brushes.length - 1) {

+ 4 - 4
base/Sources/TabFonts.ts

@@ -62,7 +62,7 @@ class TabFonts {
 
 					let uix = ui._x;
 					let tile = zui_SCALE(ui) > 1 ? 100 : 50;
-					let state = State.Idle;
+					let state = zui_state_t.IDLE;
 					if (Project.fonts[i].previewReady) {
 						// g2_set_pipeline(UIView2D.pipe); // L8
 						// ///if krom_opengl
@@ -73,10 +73,10 @@ class TabFonts {
 						// g2_set_pipeline(null);
 					}
 					else {
-						state = zui_image(Res.get("icons.k"), -1, null, tile * 6, tile, tile, tile);
+						state = zui_image(Res.get("icons.k"), -1, -1.0, tile * 6, tile, tile, tile);
 					}
 
-					if (state == State.Started) {
+					if (state == zui_state_t.STARTED) {
 						if (Context.raw.font != Project.fonts[i]) {
 							let _init = () => {
 								Context.selectFont(i);
@@ -114,7 +114,7 @@ class TabFonts {
 					if (Config.raw.show_asset_names) {
 						ui._x = uix;
 						ui._y += slotw * 0.9;
-						zui_text(Project.fonts[i].name, Align.Center);
+						zui_text(Project.fonts[i].name, zui_align_t.CENTER);
 						if (ui.is_hovered) zui_tooltip(Project.fonts[i].name);
 						ui._y -= slotw * 0.9;
 						if (i == Project.fonts.length - 1) {

+ 4 - 4
base/Sources/TabMaterials.ts

@@ -100,10 +100,10 @@ class TabMaterials {
 				let uix = ui._x;
 				let uiy = ui._y;
 				let tile = zui_SCALE(ui) > 1 ? 100 : 50;
-				let imgh: Null<f32> = mini ? UIBase.defaultSidebarMiniW * 0.85 * zui_SCALE(ui) : null;
+				let imgh: f32 = mini ? UIBase.defaultSidebarMiniW * 0.85 * zui_SCALE(ui) : -1.0;
 				let state = Project.materials[i].previewReady ?
 					zui_image(img, 0xffffffff, imgh) :
-					zui_image(Res.get("icons.k"), 0xffffffff, null, tile, tile, tile, tile);
+					zui_image(Res.get("icons.k"), 0xffffffff, -1.0, tile, tile, tile, tile);
 
 				// Draw material numbers when selecting a material via keyboard shortcut
 				let isTyping = ui.is_typing || UIView2D.ui.is_typing || UINodes.ui.is_typing;
@@ -120,7 +120,7 @@ class TabMaterials {
 				}
 
 				// Select material
-				if (state == State.Started && ui.input_y > ui._window_y) {
+				if (state == zui_state_t.STARTED && ui.input_y > ui._window_y) {
 					if (Context.raw.material != Project.materials[i]) {
 						Context.selectMaterial(i);
 						///if is_paint
@@ -235,7 +235,7 @@ class TabMaterials {
 				if (Config.raw.show_asset_names) {
 					ui._x = uix;
 					ui._y += slotw * 0.9;
-					zui_text(Project.materials[i].canvas.name, Align.Center);
+					zui_text(Project.materials[i].canvas.name, zui_align_t.CENTER);
 					if (ui.is_hovered) {
 						if (i < 9) zui_tooltip(Project.materials[i].canvas.name + " - (" + Config.keymap.select_material + " " + (i + 1) + ")");
 						else zui_tooltip(Project.materials[i].canvas.name);

+ 3 - 3
base/Sources/TabSwatches.ts

@@ -107,18 +107,18 @@ class TabSwatches {
 
 					let state = zui_image(TabSwatches.empty, Project.raw.swatches[i].base, slotw);
 
-					if (state == State.Started) {
+					if (state == zui_state_t.STARTED) {
 						Context.setSwatch(Project.raw.swatches[i]);
 
 						Base.dragOffX = -(mouse_x - uix - ui._window_x - 2 * slotw);
 						Base.dragOffY = -(mouse_y - uiy - ui._window_y + 1);
 						Base.dragSwatch = Context.raw.swatch;
 					}
-					else if (state == State.Hovered) {
+					else if (state == zui_state_t.HOVERED) {
 						TabSwatches.dragPosition = (mouse_x > uix + ui._window_x + slotw / 2) ? i + 1 : i; // Switch to the next position if the mouse crosses the swatch rectangle center
 						dragPositionSet = true;
 					}
-					else if (state == State.Released) {
+					else if (state == zui_state_t.RELEASED) {
 						if (time_time() - Context.raw.selectTime < 0.25) {
 							UIMenu.draw((ui: zui_t) => {
 								ui.changed = false;

+ 2 - 2
base/Sources/TabTextures.ts

@@ -63,7 +63,7 @@ class TabTextures {
 						let uix = ui._x;
 						let uiy = ui._y;
 						let sw = img.height < img.width ? img.height : 0;
-						if (zui_image(img, 0xffffffff, slotw, 0, 0, sw, sw) == State.Started && ui.input_y > ui._window_y) {
+						if (zui_image(img, 0xffffffff, slotw, 0, 0, sw, sw) == zui_state_t.STARTED && ui.input_y > ui._window_y) {
 							Base.dragOffX = -(mouse_x - uix - ui._window_x - 3);
 							Base.dragOffY = -(mouse_y - uiy - ui._window_y + 1);
 							Base.dragAsset = asset;
@@ -180,7 +180,7 @@ class TabTextures {
 						if (Config.raw.show_asset_names) {
 							ui._x = uix;
 							ui._y += slotw * 0.9;
-							zui_text(Project.assets[i].name, Align.Center);
+							zui_text(Project.assets[i].name, zui_align_t.CENTER);
 							if (ui.is_hovered) zui_tooltip(Project.assets[i].name);
 							ui._y -= slotw * 0.9;
 							if (i == Project.assets.length - 1) {

+ 1 - 1
base/Sources/Translator.ts

@@ -32,7 +32,7 @@ class Translator {
 
 		if (vars != null) {
 			for (let [key, value] of vars) {
-				translation = translation.replaceAll(`{${key}}`, String(value));
+				translation = string_replace_all(translation, `{${key}}`, String(value));
 			}
 		}
 

+ 4 - 4
base/Sources/UIBase.ts

@@ -201,7 +201,7 @@ class UIBase {
 		History.reset();
 
 		let scale = Config.raw.window_scale;
-		UIBase.ui = zui_create({ theme: Base.theme, font: Base.font, scaleFactor: scale, color_wheel: Base.colorWheel, black_white_gradient: Base.colorWheelGradient });
+		UIBase.ui = zui_create({ theme: Base.theme, font: Base.font, scale_factor: scale, color_wheel: Base.colorWheel, black_white_gradient: Base.colorWheelGradient });
 		zui_set_on_border_hover(UIBase.onBorderHover);
 		zui_set_on_text_hover(UIBase.onTextHover);
 		zui_set_on_deselect_text(UIBase.onDeselectText);
@@ -541,7 +541,7 @@ class UIBase {
 					UIMenu.draw((ui: zui_t) => {
 						let modeHandle = zui_handle("uibase_0");
 						modeHandle.position = Context.raw.viewportMode;
-						zui_text(tr("Viewport Mode"), Align.Right, ui.t.HIGHLIGHT_COL);
+						zui_text(tr("Viewport Mode"), zui_align_t.RIGHT, ui.t.HIGHLIGHT_COL);
 						let modes = [
 							tr("Lit"),
 							tr("Base Color"),
@@ -767,7 +767,7 @@ class UIBase {
 		let first = true;
 		UIMenu.draw((ui: zui_t) => {
 			zui_fill(0, 0, ui._w / zui_SCALE(ui), ui.t.ELEMENT_H * 8, ui.t.SEPARATOR_COL);
-			let search = zui_text_input(searchHandle, "", Align.Left, true, true);
+			let search = zui_text_input(searchHandle, "", zui_align_t.LEFT, true, true);
 			ui.changed = false;
 			if (first) {
 				first = false;
@@ -788,7 +788,7 @@ class UIBase {
 			for (let n in Config.keymap) {
 				if (n.indexOf(search) >= 0) {
 					ui.t.BUTTON_COL = count == UIBase.operatorSearchOffset ? ui.t.HIGHLIGHT_COL : ui.t.SEPARATOR_COL;
-					if (zui_button(n, Align.Left, Config.keymap[n]) || (enter && count == UIBase.operatorSearchOffset)) {
+					if (zui_button(n, zui_align_t.LEFT, Config.keymap[n]) || (enter && count == UIBase.operatorSearchOffset)) {
 						if (enter) {
 							ui.changed = true;
 							count = 6; // Trigger break

+ 2 - 2
base/Sources/UIBox.ts

@@ -20,7 +20,7 @@ class UIBox {
 	static render = () => {
 		if (!UIMenu.show) {
 			let ui = Base.uiBox;
-			let inUse = ui.combo_selected_handle_ptr != null;
+			let inUse = ui.combo_selected_handle_ptr != 0;
 			let isEscape = keyboard_started("escape");
 			if (UIBox.draws > 2 && (ui.input_released || isEscape) && !inUse && !ui.is_typing) {
 				let appw = sys_width();
@@ -69,7 +69,7 @@ class UIBox {
 					let htext = zui_handle("uibox_1");
 					htext.text = UIBox.boxText;
 					UIBox.copyable ?
-						zui_text_area(htext, Align.Left, false) :
+						zui_text_area(htext, zui_align_t.LEFT, false) :
 						zui_text(UIBox.boxText);
 					zui_end_element();
 

+ 8 - 8
base/Sources/UIFiles.ts

@@ -27,8 +27,8 @@ class UIFiles {
 		if (isSave) {
 			UIFiles.path = krom_save_dialog(filters, "");
 			if (UIFiles.path != null) {
-				while (UIFiles.path.indexOf(Path.sep + Path.sep) >= 0) UIFiles.path = UIFiles.path.replaceAll(Path.sep + Path.sep, Path.sep);
-				UIFiles.path = UIFiles.path.replaceAll("\r", "");
+				while (UIFiles.path.indexOf(Path.sep + Path.sep) >= 0) UIFiles.path = string_replace_all(UIFiles.path, Path.sep + Path.sep, Path.sep);
+				UIFiles.path = string_replace_all(UIFiles.path, "\r", "");
 				UIFiles.filename = UIFiles.path.substr(UIFiles.path.lastIndexOf(Path.sep) + 1);
 				UIFiles.path = UIFiles.path.substr(0, UIFiles.path.lastIndexOf(Path.sep));
 				filesDone(UIFiles.path);
@@ -38,8 +38,8 @@ class UIFiles {
 			let paths = krom_open_dialog(filters, "", openMultiple);
 			if (paths != null) {
 				for (let path of paths) {
-					while (path.indexOf(Path.sep + Path.sep) >= 0) path = path.replaceAll(Path.sep + Path.sep, Path.sep);
-					path = path.replaceAll("\r", "");
+					while (path.indexOf(Path.sep + Path.sep) >= 0) path = string_replace_all(path, Path.sep + Path.sep, Path.sep);
+					path = string_replace_all(path, "\r", "");
 					UIFiles.filename = path.substr(path.lastIndexOf(Path.sep) + 1);
 					filesDone(path);
 				}
@@ -156,7 +156,7 @@ class UIFiles {
 
 				let uix = ui._x;
 				let uiy = ui._y;
-				let state = State.Idle;
+				let state = zui_state_t.IDLE;
 				let generic = true;
 				let icon: image_t = null;
 
@@ -316,7 +316,7 @@ class UIFiles {
 					contextMenu(handle.text + Path.sep + f);
 				}
 
-				if (state == State.Started) {
+				if (state == zui_state_t.STARTED) {
 					if (f != ".." && dragFiles) {
 						Base.dragOffX = -(mouse_x - uix - ui._window_x - 3);
 						Base.dragOffY = -(mouse_y - uiy - ui._window_y + 1);
@@ -363,12 +363,12 @@ class UIFiles {
 					label0 = label0.substr(0, label0.length - 1);
 				}
 				if (label1 != "") ui.cur_ratio--;
-				zui_text(label0, Align.Center);
+				zui_text(label0, zui_align_t.CENTER);
 				if (ui.is_hovered) zui_tooltip(label0 + label1);
 				if (label1 != "") { // Second line
 					ui._x = _x;
 					ui._y += g2_font_height(ui.font, ui.font_size);
-					zui_text(label1, Align.Center);
+					zui_text(label1, zui_align_t.CENTER);
 					if (ui.is_hovered) zui_tooltip(label0 + label1);
 					ui._y -= g2_font_height(ui.font, ui.font_size);
 				}

+ 3 - 3
base/Sources/UIHeader.ts

@@ -3,7 +3,7 @@ class UIHeader {
 
 	static defaultHeaderH = 28;
 	static headerh = UIHeader.defaultHeaderH;
-	static headerHandle = zui_handle_create({ layout: Layout.Horizontal });
+	static headerHandle = zui_handle_create({ layout: zui_layout_t.HORIZONTAL });
 	static worktab = zui_handle_create();
 
 	constructor() {
@@ -120,7 +120,7 @@ class UIHeader {
 			color = color_set_bb(color, baseBPicked * 255);
 			h.color = color;
 			let state = zui_text("", 0, h.color);
-			if (state == State.Started) {
+			if (state == zui_state_t.STARTED) {
 				let uix = ui._x;
 				let uiy = ui._y;
 				Base.dragOffX = -(mouse_x - uix - ui._window_x - 3);
@@ -375,7 +375,7 @@ class UIHeader {
 					ui._w *= 3;
 				}
 
-				Context.raw.textToolText = zui_text_input(h, "", Align.Left, true, true);
+				Context.raw.textToolText = zui_text_input(h, "", zui_align_t.LEFT, true, true);
 				ui._w = w;
 
 				if (h.changed) {

+ 5 - 5
base/Sources/UIMenu.ts

@@ -371,7 +371,7 @@ class UIMenu {
 				UIMenu.menuAlign(ui);
 				let cameraControlsHandle = zui_handle("uimenu_12");
 				cameraControlsHandle.position = Context.raw.cameraControls;
-				Context.raw.cameraControls = zui_inline_radio(cameraControlsHandle, [tr("Orbit"), tr("Rotate"), tr("Fly")], Align.Left);
+				Context.raw.cameraControls = zui_inline_radio(cameraControlsHandle, [tr("Orbit"), tr("Rotate"), tr("Fly")], zui_align_t.LEFT);
 
 				let orbitAndRotateTooltip = tr("Orbit and Rotate mode:\n{rotate_shortcut} or move right mouse button to rotate.\n{zoom_shortcut} or scroll to zoom.\n{pan_shortcut} or move middle mouse to pan.",
 					new Map([
@@ -385,7 +385,7 @@ class UIMenu {
 
 				UIMenu.menuFill(ui);
 				UIMenu.menuAlign(ui);
-				Context.raw.cameraType = zui_inline_radio(Context.raw.camHandle, [tr("Perspective"), tr("Orthographic")], Align.Left);
+				Context.raw.cameraType = zui_inline_radio(Context.raw.camHandle, [tr("Perspective"), tr("Orthographic")], zui_align_t.LEFT);
 				if (ui.is_hovered) zui_tooltip(tr("Camera Type") + ` (${Config.keymap.view_camera_type})`);
 				if (Context.raw.camHandle.changed) {
 					Viewport.updateCameraType(Context.raw.cameraType);
@@ -436,7 +436,7 @@ class UIMenu {
 							let updateVersion = Math.floor(update.version);
 							if (updateVersion > 0) {
 								let date = Config.getDate().substr(2); // 2019 -> 19
-								let dateInt = parseInt(date.replaceAll("-", ""));
+								let dateInt = parseInt(string_replace_all(date, "-", ""));
 								if (updateVersion > dateInt) {
 									UIBox.showMessage(tr("Update"), tr("Update is available!\nPlease visit {url}.", new Map([["url", manifest_url]])));
 								}
@@ -488,7 +488,7 @@ class UIMenu {
 							zui_image(img);
 							zui_end_element();
 
-							zui_text_area(zui_handle("uimenu_14", { text: msg }), Align.Left, false);
+							zui_text_area(zui_handle("uimenu_14", { text: msg }), zui_align_t.LEFT, false);
 
 							zui_row([1 / 3, 1 / 3, 1 / 3]);
 
@@ -512,7 +512,7 @@ class UIMenu {
 			}
 		}
 
-		UIMenu.hideMenu = ui.combo_selected_handle_ptr == null && !UIMenu.keepOpen && !UIMenu.showMenuFirst && (ui.changed || ui.input_released || ui.input_released_r || ui.is_escape_down);
+		UIMenu.hideMenu = ui.combo_selected_handle_ptr == 0 && !UIMenu.keepOpen && !UIMenu.showMenuFirst && (ui.changed || ui.input_released || ui.input_released_r || ui.is_escape_down);
 		UIMenu.showMenuFirst = false;
 		UIMenu.keepOpen = false;
 

+ 3 - 3
base/Sources/UIMenubar.ts

@@ -2,8 +2,8 @@
 class UIMenubar {
 
 	static defaultMenubarW = 330;
-	static workspaceHandle = zui_handle_create({ layout: Layout.Horizontal });
-	static menuHandle = zui_handle_create({ layout: Layout.Horizontal });
+	static workspaceHandle = zui_handle_create({ layout: zui_layout_t.HORIZONTAL });
+	static menuHandle = zui_handle_create({ layout: zui_layout_t.HORIZONTAL });
 	static menubarw = UIMenubar.defaultMenubarW;
 
 	///if is_lab
@@ -182,6 +182,6 @@ class UIMenubar {
 		let iconAccent = light ? 0xff666666 : 0xffaaaaaa;
 		let img = Res.get("icons.k");
 		let rect = Res.tile50(img, i, j);
-		return zui_image(img, iconAccent, null, rect.x, rect.y, rect.w, rect.h) == State.Released;
+		return zui_image(img, iconAccent, -1.0, rect.x, rect.y, rect.w, rect.h) == zui_state_t.RELEASED;
 	}
 }

+ 10 - 10
base/Sources/UINodes.ts

@@ -44,7 +44,7 @@ class UINodes {
 		zui_set_on_canvas_control(UINodes.onCanvasControl);
 
 		let scale = Config.raw.window_scale;
-		UINodes.ui = zui_create({ theme: Base.theme, font: Base.font, color_wheel: Base.colorWheel, black_white_gradient: Base.colorWheelGradient, scaleFactor: scale });
+		UINodes.ui = zui_create({ theme: Base.theme, font: Base.font, color_wheel: Base.colorWheel, black_white_gradient: Base.colorWheelGradient, scale_factor: scale });
 		UINodes.ui.scroll_enabled = false;
 	}
 
@@ -352,8 +352,8 @@ class UINodes {
 		}
 		if (!parent.controlsDown) {
 			return {
-				panX: 0,
-				panY: 0,
+				pan_x: 0,
+				pan_y: 0,
 				zoom: 0
 			}
 		}
@@ -361,8 +361,8 @@ class UINodes {
 		let pan = ui.input_down_r || Operator.shortcut(Config.keymap.action_pan, ShortcutType.ShortcutDown);
 		let zoomDelta = Operator.shortcut(Config.keymap.action_zoom, ShortcutType.ShortcutDown) ? UINodes.getZoomDelta(ui) / 100.0 : 0.0;
 		let control = {
-			panX: pan ? ui.input_dx : 0.0,
-			panY: pan ? ui.input_dy : 0.0,
+			pan_x: pan ? ui.input_dx : 0.0,
+			pan_y: pan ? ui.input_dy : 0.0,
 			zoom: ui.input_wheel_delta != 0.0 ? -ui.input_wheel_delta / 10 : zoomDelta
 		};
 		if (Base.isComboSelected()) control.zoom = 0.0;
@@ -477,7 +477,7 @@ class UINodes {
 			zui_draw_rect(true, ui._x, ui._y, ui._w, zui_ELEMENT_H(ui) * 8);
 			g2_set_color(0xffffffff);
 
-			let search = zui_text_input(searchHandle, "", Align.Left, true, true).toLowerCase();
+			let search = zui_text_input(searchHandle, "", zui_align_t.LEFT, true, true).toLowerCase();
 			ui.changed = false;
 			if (first) {
 				first = false;
@@ -506,7 +506,7 @@ class UINodes {
 				for (let n of list) {
 					if (tr(n.name).toLowerCase().indexOf(search) >= 0) {
 						ui.t.BUTTON_COL = count == UINodes.nodeSearchOffset ? ui.t.HIGHLIGHT_COL : ui.t.SEPARATOR_COL;
-						if (zui_button(tr(n.name), Align.Left) || (enter && count == UINodes.nodeSearchOffset)) {
+						if (zui_button(tr(n.name), zui_align_t.LEFT) || (enter && count == UINodes.nodeSearchOffset)) {
 							UINodes.pushUndo();
 							let nodes = UINodes.getNodes();
 							let canvas = UINodes.getCanvas(true);
@@ -1055,7 +1055,7 @@ class UINodes {
 					UINodes.ui.enabled = UINodes.canPlaceGroup(g.canvas.name);
 					UIMenu.menuFill(UINodes.ui);
 					zui_row([5 / 6, 1 / 6]);
-					if (zui_button(Config.buttonSpacing + g.canvas.name, Align.Left)) {
+					if (zui_button(Config.buttonSpacing + g.canvas.name, zui_align_t.LEFT)) {
 						UINodes.pushUndo();
 						let canvas = UINodes.getCanvas(true);
 						let nodes = UINodes.getNodes();
@@ -1067,7 +1067,7 @@ class UINodes {
 
 					///if (is_paint || is_sculpt)
 					UINodes.ui.enabled = !Project.isMaterialGroupInUse(g);
-					if (zui_button("x", Align.Center)) {
+					if (zui_button("x", zui_align_t.CENTER)) {
 						History.deleteMaterialGroup(g);
 						array_remove(Project.materialGroups, g);
 					}
@@ -1077,7 +1077,7 @@ class UINodes {
 				}
 			}
 
-			UINodes.hideMenu = UINodes.ui.combo_selected_handle_ptr == null && !UINodes.showMenuFirst && (UINodes.ui.changed || UINodes.ui.input_released || UINodes.ui.input_released_r || UINodes.ui.is_escape_down);
+			UINodes.hideMenu = UINodes.ui.combo_selected_handle_ptr == 0 && !UINodes.showMenuFirst && (UINodes.ui.changed || UINodes.ui.input_released || UINodes.ui.input_released_r || UINodes.ui.is_escape_down);
 			UINodes.showMenuFirst = false;
 
 			UINodes.ui.t.BUTTON_COL = _BUTTON_COL;

+ 5 - 5
base/Sources/UIToolbar.ts

@@ -55,7 +55,7 @@ class UIToolbar {
 			// Properties icon
 			if (Config.raw.layout[LayoutSize.LayoutHeader] == 1) {
 				let rect = Res.tile50(img, 7, 1);
-				if (zui_image(img, light ? 0xff666666 : ui.t.BUTTON_COL, null, rect.x, rect.y, rect.w, rect.h) == State.Released) {
+				if (zui_image(img, light ? 0xff666666 : ui.t.BUTTON_COL, -1.0, rect.x, rect.y, rect.w, rect.h) == zui_state_t.RELEASED) {
 					Config.raw.layout[LayoutSize.LayoutHeader] = 0;
 				}
 			}
@@ -111,11 +111,11 @@ class UIToolbar {
 				let rect = Res.tile50(img, tileX, tileY);
 				let _y = ui._y;
 
-				let imageState = zui_image(img, iconAccent, null, rect.x, rect.y, rect.w, rect.h);
-				if (imageState == State.Started) {
+				let imageState = zui_image(img, iconAccent, -1.0, rect.x, rect.y, rect.w, rect.h);
+				if (imageState == zui_state_t.STARTED) {
 					Context.selectTool(i);
 				}
-				else if (imageState == State.Released && Config.raw.layout[LayoutSize.LayoutHeader] == 0) {
+				else if (imageState == zui_state_t.RELEASED && Config.raw.layout[LayoutSize.LayoutHeader] == 0) {
 					if (UIToolbar.lastTool == i) {
 						UIToolbar.toolPropertiesMenu();
 					}
@@ -180,7 +180,7 @@ class UIToolbar {
 				UIMenu.keepOpen = true;
 			}
 
-			if (zui_button(tr("Pin to Header"), Align.Left)) {
+			if (zui_button(tr("Pin to Header"), zui_align_t.LEFT)) {
 				Config.raw.layout[LayoutSize.LayoutHeader] = 1;
 			}
 

+ 3 - 3
base/Sources/UIView2D.ts

@@ -47,7 +47,7 @@ class UIView2D {
 		///end
 
 		let scale = Config.raw.window_scale;
-		UIView2D.ui = zui_create({ theme: Base.theme, font: Base.font, color_wheel: Base.colorWheel, black_white_gradient: Base.colorWheelGradient, scaleFactor: scale });
+		UIView2D.ui = zui_create({ theme: Base.theme, font: Base.font, color_wheel: Base.colorWheel, black_white_gradient: Base.colorWheelGradient, scale_factor: scale });
 		UIView2D.ui.scroll_enabled = false;
 	}
 
@@ -397,8 +397,8 @@ class UIView2D {
 		}
 
 		let control = UINodes.getCanvasControl(UIView2D.ui, UIView2D);
-		UIView2D.panX += control.panX;
-		UIView2D.panY += control.panY;
+		UIView2D.panX += control.pan_x;
+		UIView2D.panY += control.pan_y;
 		if (control.zoom != 0) {
 			let _panX = UIView2D.panX / UIView2D.panScale;
 			let _panY = UIView2D.panY / UIView2D.panScale;

+ 3 - 2
base/Sources/UtilRender.ts

@@ -80,7 +80,8 @@ class UtilRender {
 
 	static makeDecalPreview = () => {
 		let current = _g2_current;
-		if (current != null) g2_end();
+		let g2_in_use = _g2_in_use;
+		if (g2_in_use) g2_end();
 
 		if (Context.raw.decalImage == null) {
 			Context.raw.decalImage = image_create_render_target(UtilRender.decalPreviewSize, UtilRender.decalPreviewSize);
@@ -141,7 +142,7 @@ class UtilRender {
 		MakeMaterial.parseMeshMaterial();
 		Context.raw.ddirty = 1; // Refresh depth for decal paint
 
-		if (current != null) g2_begin(current);
+		if (g2_in_use) g2_begin(current);
 	}
 
 	static makeTextPreview = () => {

+ 19 - 20
base/Sources/main.ts

@@ -37,26 +37,25 @@ function main_start() {
 	app_on_y = Base.y;
 
 	Config.init();
-	sys_start(Config.getOptions(), function() {
-		if (Config.raw.layout == null) Base.initLayout();
-		krom_set_app_name(manifest_title);
-		app_init(function() {
-			let o: object_t = scene_set_active("Scene");
-			UniformsExt.init();
-			RenderPathBase.init();
-
-			if (Context.raw.renderMode == RenderMode.RenderForward) {
-				RenderPathDeferred.init(); // Allocate gbuffer
-				RenderPathForward.init();
-				render_path_commands = RenderPathForward.commands;
-			}
-			else {
-				RenderPathDeferred.init();
-				render_path_commands = RenderPathDeferred.commands;
-			}
-
-			new Base();
-		});
+	sys_start(Config.getOptions());
+	if (Config.raw.layout == null) Base.initLayout();
+	krom_set_app_name(manifest_title);
+	app_init(function() {
+		let o: object_t = scene_set_active("Scene");
+		UniformsExt.init();
+		RenderPathBase.init();
+
+		if (Context.raw.renderMode == RenderMode.RenderForward) {
+			RenderPathDeferred.init(); // Allocate gbuffer
+			RenderPathForward.init();
+			render_path_commands = RenderPathForward.commands;
+		}
+		else {
+			RenderPathDeferred.init();
+			render_path_commands = RenderPathDeferred.commands;
+		}
+
+		new Base();
 	});
 }
 

+ 125 - 128
misc/pad/Sources/main.ts

@@ -1,128 +1,125 @@
 
 type storage_t = {
-	project: string;
-	file: string;
-	text: string;
-	modified: bool;
-	expanded: string[];
-	window_w: i32;
-	window_h: i32;
-	window_x: i32;
-	window_y: i32;
-	sidebar_w: i32;
+	project?: string;
+	file?: string;
+	text?: string;
+	modified?: bool;
+	expanded?: string[];
+	window_w?: i32;
+	window_h?: i32;
+	window_x?: i32;
+	window_y?: i32;
+	sidebar_w?: i32;
 };
 
 let ui: zui_t;
-let text_handle = zui_handle_create();
-let sidebar_handle = zui_handle_create();
-let editor_handle = zui_handle_create();
+let text_handle: zui_handle_t = zui_handle_create();
+let sidebar_handle: zui_handle_t = zui_handle_create();
+let editor_handle: zui_handle_t = zui_handle_create();
 let storage: storage_t = null;
-let resizing_sidebar = false;
-let minimap_w = 150;
-let minimap_h = 0;
-let minimap_box_h = 0;
-let minimap_scrolling = false;
+let resizing_sidebar: bool = false;
+let minimap_w: i32 = 150;
+let minimap_h: i32 = 0;
+let minimap_box_h: i32 = 0;
+let minimap_scrolling: bool = false;
 let minimap: image_t = null;
-let window_header_h = 0;
+let window_header_h: i32 = 0;
+
+function drop_files(path: string) {
+	storage.project = path;
+	sidebar_handle.redraws = 1;
+}
+
+function shutdown() {
+	krom_file_save_bytes(krom_save_path() + "/config.json", sys_string_to_buffer(json_stringify(storage)));
+}
 
 function main() {
 	zui_set_text_area_line_numbers(true);
 	zui_set_text_area_scroll_past_end(true);
 
-	krom_set_application_name("ArmorPad");
-	let blob_storage = krom_load_blob(krom_save_path() + "/config.json");
+	krom_set_app_name("ArmorPad");
+	let blob_storage: buffer_t = krom_load_blob(krom_save_path() + "/config.json");
 	if (blob_storage == null) {
-		storage = {
-			project: "",
-			file: "untitled",
-			text: "",
-			modified: false,
-			expanded: [],
-			window_w: 1600,
-			window_h: 900,
-			window_x: -1,
-			window_y: -1,
-			sidebar_w: 230,
-		};
+		storage = {};
+		storage.project = "";
+		storage.file = "untitled";
+		storage.text = "";
+		storage.modified = false;
+		storage.expanded = [];
+		storage.window_w = 1600;
+		storage.window_h = 900;
+		storage.window_x = -1;
+		storage.window_y = -1;
+		storage.sidebar_w = 230;
 	}
 	else {
-		storage = JSON.parse(sys_buffer_to_string(blob_storage));
+		storage = json_parse(sys_buffer_to_string(blob_storage));
 	}
 
 	text_handle.text = storage.text;
-	let ops: kinc_sys_ops_t = {
-		title: "ArmorPad",
-		x: storage.window_x,
-		y: storage.window_y,
-		width: storage.window_w,
-		height: storage.window_h,
-		features: WindowFeatures.FeatureResizable | WindowFeatures.FeatureMaximizable | WindowFeatures.FeatureMinimizable,
-		mode: WindowMode.Windowed,
-		frequency: 60,
-		vsync: true
-	};
-
-	sys_start(ops, function() {
-		data_get_font("font_mono.ttf", function (font: font_t) {
-			data_get_blob("themes/dark.json", function (blob_theme: ArrayBuffer) {
-				data_get_blob("text_coloring.json", function (blob_coloring: ArrayBuffer) {
-
-					let parsed = JSON.parse(sys_buffer_to_string(blob_theme));
-					let theme: any = zui_theme_create();
-					for (let key of Object.getOwnPropertyNames(theme_t.prototype)) {
-						if (key == "constructor") {
-							continue;
-						}
-						theme[key] = parsed[key];
-					}
-
-					g2_font_init(font);
-					ui = zui_create({ theme: theme, font: font, scaleFactor: 1.0, color_wheel: null, black_white_gradient: null });
-					zui_set_on_border_hover(on_border_hover);
-					zui_set_on_text_hover(on_text_hover);
-
-					let text_coloring: zui_text_coloring_t = JSON.parse(sys_buffer_to_string(blob_coloring));
-					text_coloring.default_color = Math.floor(text_coloring.default_color);
-					for (let coloring of text_coloring.colorings) {
-						coloring.color = Math.floor(coloring.color);
-					}
-					zui_set_text_area_coloring(text_coloring);
-
-					sys_notify_on_frames(render);
-				});
-			});
-		});
-	});
-
-	krom_set_drop_files_callback(function (path: string) {
-		storage.project = path;
-		sidebar_handle.redraws = 1;
-	});
-
-	krom_set_application_state_callback(
-		function() {},
-		function() {},
-		function() {},
-		function() {},
-		function () { // Shutdown
-			krom_file_save_bytes(krom_save_path() + "/config.json", sys_string_to_buffer(JSON.stringify(storage)));
+
+	let ops: kinc_sys_ops_t = {};
+	ops.title = "ArmorPad";
+	ops.x = storage.window_x;
+	ops.y = storage.window_y;
+	ops.width = storage.window_w;
+	ops.height = storage.window_h;
+	ops.features = window_features_t.RESIZABLE | window_features_t.MAXIMIZABLE | window_features_t.MINIMIZABLE;
+	ops.mode = window_mode_t.WINDOWED;
+	ops.frequency = 60;
+	ops.vsync = true;
+	sys_start(ops);
+
+	let font: g2_font_t = data_get_font("font_mono.ttf");
+	let blob_theme: buffer_t = data_get_blob("themes/dark.json");
+	let blob_coloring: buffer_t = data_get_blob("text_coloring.json");
+	let parsed: any = json_parse(sys_buffer_to_string(blob_theme));
+	let theme: any = zui_theme_create();
+	for (let key of Object.getOwnPropertyNames(theme_t.prototype)) {
+		if (key == "constructor") {
+			continue;
 		}
-	);
+		theme[key] = parsed[key];
+	}
+
+	g2_font_init(font);
+	let zui_ops: zui_ops_t = {};
+	zui_ops.theme = theme;
+	zui_ops.font = font;
+	zui_ops.scaleFactor = 1.0;
+	zui_ops.color_wheel = null;
+	zui_ops.black_white_gradient = null;
+	ui = zui_create(zui_ops);
+	zui_set_on_border_hover(on_border_hover);
+	zui_set_on_text_hover(on_text_hover);
+
+	let text_coloring: zui_text_coloring_t = json_parse(sys_buffer_to_string(blob_coloring));
+	text_coloring.default_color = math_floor(text_coloring.default_color);
+	for (let coloring of text_coloring.colorings) {
+		coloring.color = math_floor(coloring.color);
+	}
+	zui_set_text_area_coloring(text_coloring);
+
+	sys_notify_on_frames(render);
+	krom_set_drop_files_callback(drop_files);
+	krom_set_application_state_callback(null, null, null, null, shutdown);
 }
 
 function list_folder(path: string) {
-	let files = krom_read_directory(path, false).split("\n");
-	for (let f of files) {
-		let abs = path + "/" + f;
-		let is_file = f.indexOf(".") >= 0;
-		let is_expanded = storage.expanded.indexOf(abs) >= 0;
+	let files: string[] = string_split(krom_read_directory(path, false), "\n");
+	for (let i: i32 = 0; i < files.length; ++i) {
+		let f: string = files[i];
+		let abs: string = path + "/" + f;
+		let is_file: bool = string_index_of(f, ".") >= 0;
+		let is_expanded: bool = array_index_of(storage.expanded, abs) >= 0;
 
 		// Active file
 		if (abs == storage.file) {
 			zui_fill(0, 1, ui._w - 1, zui_ELEMENT_H(ui) - 1, ui.t.BUTTON_PRESSED_COL);
 		}
 
-		let prefix = "";
+		let prefix: string = "";
 		if (!is_file) {
 			prefix = is_expanded ? "- " : "+ ";
 		}
@@ -131,8 +128,8 @@ function list_folder(path: string) {
 			// Open file
 			if (is_file) {
 				storage.file = abs;
-				let bytes = krom_load_blob(storage.file);
-				storage.text = f.endsWith(".arm") ? JSON.stringify(armpack_decode(bytes), null, 4) : sys_buffer_to_string(bytes);
+				let bytes: buffer_t = krom_load_blob(storage.file);
+				storage.text = f.endsWith(".arm") ? json_stringify(armpack_decode(bytes)) : sys_buffer_to_string(bytes);
 				storage.text = storage.text.replaceAll("\r", "");
 				text_handle.text = storage.text;
 				editor_handle.redraws = 1;
@@ -140,7 +137,7 @@ function list_folder(path: string) {
 			}
 			// Expand folder
 			else {
-				storage.expanded.indexOf(abs) == -1 ? storage.expanded.push(abs) : array_remove(storage.expanded, abs);
+				array_index_of(storage.expanded, abs) == -1 ? array_push(storage.expanded, abs) : array_remove(storage.expanded, abs);
 			}
 		}
 
@@ -164,7 +161,7 @@ function render() {
 	zui_begin(ui);
 
 	if (zui_window(sidebar_handle, 0, 0, storage.sidebar_w, sys_height(), false)) {
-		let _BUTTON_TEXT_COL = ui.t.BUTTON_TEXT_COL;
+		let _BUTTON_TEXT_COL: i32 = ui.t.BUTTON_TEXT_COL;
 		ui.t.BUTTON_TEXT_COL = ui.t.ACCENT_COL;
 		if (storage.project != "") {
 			list_folder(storage.project);
@@ -178,13 +175,13 @@ function render() {
 	zui_fill(sys_width() - minimap_w, 0, minimap_w, zui_ELEMENT_H(ui) + zui_ELEMENT_OFFSET(ui) + 1, ui.t.SEPARATOR_COL);
 	zui_fill(storage.sidebar_w, 0, 1, sys_height(), ui.t.SEPARATOR_COL);
 
-	let editor_updated = false;
+	let editor_updated: bool = false;
 
 	if (zui_window(editor_handle, storage.sidebar_w + 1, 0, sys_width() - storage.sidebar_w - minimap_w, sys_height(), false)) {
 		editor_updated = true;
-		let htab = zui_handle("main_0", { position: 0 });
-		let file_name = storage.file.substring(storage.file.lastIndexOf("/") + 1);
-		let file_names = [file_name];
+		let htab: zui_handle_t = zui_handle("main_0", { position: 0 });
+		let file_name: string = storage.file.substring(storage.file.lastIndexOf("/") + 1);
+		let file_names: string[] = [file_name];
 
 		for (let file_name of file_names) {
 			if (zui_tab(htab, file_name + (storage.modified ? "*" : ""))) {
@@ -194,7 +191,7 @@ function render() {
 				}
 
 				// Save
-				if (ui.is_ctrl_down && ui.key == KeyCode.S) {
+				if (ui.is_ctrl_down && ui.key == key_code_t.S) {
 					save_file();
 				}
 
@@ -202,20 +199,20 @@ function render() {
 			}
 		}
 
-		window_header_h = 32;//Math.floor(ui.windowHeaderH);
+		window_header_h = 32;//math_floor(ui.windowHeaderH);
 	}
 
 	if (resizing_sidebar) {
-		storage.sidebar_w += Math.floor(ui.input_dx);
+		storage.sidebar_w += math_floor(ui.input_dx);
 	}
 	if (!ui.input_down) {
 		resizing_sidebar = false;
 	}
 
 	// Minimap controls
-	let minimap_x = sys_width() - minimap_w;
-	let minimap_y = window_header_h + 1;
-	let redraw = false;
+	let minimap_x: i32 = sys_width() - minimap_w;
+	let minimap_y: i32 = window_header_h + 1;
+	let redraw: bool = false;
 	if (ui.input_started && hit_test(ui.input_x, ui.input_y, minimap_x + 5, minimap_y, minimap_w, minimap_h)) {
 		minimap_scrolling = true;
 	}
@@ -229,7 +226,7 @@ function render() {
 	}
 
 	// Build project
-	if (ui.is_ctrl_down && ui.key == KeyCode.B) {
+	if (ui.is_ctrl_down && ui.key == key_code_t.B) {
 		save_file();
 		build_project();
 	}
@@ -253,16 +250,16 @@ function render() {
 
 function save_file() {
 	// Trim
-	let lines = storage.text.split("\n");
+	let lines: string[] = string_split(storage.text, "\n");
 	for (let i = 0; i < lines.length; ++i) {
 		lines[i] = trim_end(lines[i]);
 	}
 	storage.text = lines.join("\n");
 	// Spaces to tabs
-	storage.text = storage.text.replaceAll("    ", "\t");
+	storage.text = string_replace_all(storage.text, "    ", "\t");
 	text_handle.text = storage.text;
 	// Write bytes
-	let bytes = storage.file.endsWith(".arm") ? armpack_encode(JSON.parse(storage.text)) : sys_string_to_buffer(storage.text);
+	let bytes = ends_with(storage.file, ".arm") ? armpack_encode(json_parse(storage.text)) : sys_string_to_buffer(storage.text);
 	krom_file_save_bytes(storage.file, bytes, bytes.byteLength);
 	storage.modified = false;
 }
@@ -291,34 +288,34 @@ function draw_minimap() {
 	g2_begin(minimap);
 	g2_clear(ui.t.SEPARATOR_COL);
 	g2_set_color(0xff333333);
-	let lines = storage.text.split("\n");
-	let minimap_full_h = lines.length * 2;
-	let scrollProgress = -editor_handle.scroll_offset / (lines.length * zui_ELEMENT_H(ui));
-	let out_of_screen = minimap_full_h - minimap_h;
+	let lines: string[] = string_split(storage.text, "\n");
+	let minimap_full_h: i32 = lines.length * 2;
+	let scroll_progress: f32 = -editor_handle.scroll_offset / (lines.length * zui_ELEMENT_H(ui));
+	let out_of_screen: i32 = minimap_full_h - minimap_h;
 	if (out_of_screen < 0) {
 		out_of_screen = 0;
 	}
-	let offset = Math.floor((out_of_screen * scrollProgress) / 2);
+	let offset: i32 = math_floor((out_of_screen * scroll_progress) / 2);
 
-	for (let i = 0; i < lines.length; ++i) {
+	for (let i: i32 = 0; i < lines.length; ++i) {
 		if (i * 2 > minimap_h || i + offset >= lines.length) {
 			// Out of screen
 			break;
 		}
-		let words = lines[i + offset].split(" ");
-		let x = 0;
-		for (let j = 0; j < words.length; ++j) {
-			let word = words[j];
+		let words: string[] = string_split(lines[i + offset], " ");
+		let x: i32 = 0;
+		for (let j: i32 = 0; j < words.length; ++j) {
+			let word: string = words[j];
 			g2_fill_rect(x, i * 2, word.length, 2);
 			x += word.length + 1;
 		}
 	}
 
 	// Current position
-	let visible_area = out_of_screen > 0 ? minimap_h : minimap_full_h;
+	let visible_area: i32 = out_of_screen > 0 ? minimap_h : minimap_full_h;
 	g2_set_color(0x11ffffff);
-	minimap_box_h = Math.floor((sys_height() - window_header_h) / zui_ELEMENT_H(ui) * 2);
-	g2_fill_rect(0, scrollProgress * visible_area, minimap_w, minimap_box_h);
+	minimap_box_h = math_floor((sys_height() - window_header_h) / zui_ELEMENT_H(ui) * 2);
+	g2_fill_rect(0, scroll_progress * visible_area, minimap_w, minimap_box_h);
 	g2_end();
 }