diff --git a/loc/en_GB.ts b/loc/en_GB.ts index 7c40944..216ff9e 100644 --- a/loc/en_GB.ts +++ b/loc/en_GB.ts @@ -39,6 +39,7 @@ export const en_GB = { unsupported_image_type: 'Cannot read \'{{file_name}}\', unsupported file type \'{{file_type}}\'', components: { input: '3D Model (.obj, .glb)', + no_file_chosen: 'No file chosen', rotation: 'Rotation', }, }, @@ -162,5 +163,24 @@ export const en_GB = { off: 'Off', advanced_settings: 'Advanced settings' }, + toolbar: { + view_mesh: 'View mesh', + view_voxel_mesh: 'View voxel mesh', + view_block_mesh: 'View block mesh', + toggle_grid: 'Toggle grid', + toggle_axes: 'Toggle axes', + toggle_night_vision: 'Toggle night vision', + toggle_slice_viewer: 'Toggle slice viewer', + decrement_slice: 'Decrement slice', + increment_slice: 'Increment slice', + zoom_in: 'Zoom in', + zoom_out: 'Zoom out', + reset_camera: 'Reset camera', + perspective_camera: 'Perspective camera', + orthographic_camera: 'Orthographic camera', + open_github_repo: 'Open GitHub repo', + open_github_issues: 'Open GitHub issues', + join_discord: 'Join Discord server', + } }, }; diff --git a/src/config.ts b/src/config.ts index 5adeba7..cfe52c9 100644 --- a/src/config.ts +++ b/src/config.ts @@ -11,7 +11,7 @@ export class AppConfig { public readonly RELEASE_MODE; public readonly MAJOR_VERSION = 0; public readonly MINOR_VERSION = 8; - public readonly HOTFIX_VERSION = 6; + public readonly HOTFIX_VERSION = 7; public readonly VERSION_TYPE: 'd' | 'a' | 'r' = 'r'; // dev, alpha, or release build public readonly MINECRAFT_VERSION = '1.19.4'; diff --git a/src/localiser.ts b/src/localiser.ts index cf5b371..6b867eb 100644 --- a/src/localiser.ts +++ b/src/localiser.ts @@ -23,6 +23,8 @@ export type Concat = export type TLocalisedString = TBrand; +export type TLocalisedKey = DeepLeafKeys; + export class Localiser { /* Singleton */ private static _instance: Localiser; diff --git a/src/ui/components/file_input.ts b/src/ui/components/file_input.ts index 67acd4d..1c1499c 100644 --- a/src/ui/components/file_input.ts +++ b/src/ui/components/file_input.ts @@ -4,6 +4,7 @@ import { ASSERT } from '../../util/error_util'; import { UIUtil } from '../../util/ui_util'; import { ConfigComponent } from './config'; import { AppIcons } from '../icons'; +import { LOC } from '../../localiser'; export class FileComponent extends ConfigComponent { private _loadedFilePath: string | null; @@ -17,7 +18,7 @@ export class FileComponent extends ConfigComponent { return `
- ${this._loadedFilePath ?? 'No file chosen'} + ${this._loadedFilePath ?? LOC('import.components.no_file_chosen')}
`; } @@ -67,7 +68,7 @@ export class FileComponent extends ConfigComponent { const parsedPath = path.parse(this._loadedFilePath); this._getElement().innerHTML = parsedPath.name + parsedPath.ext; } else { - this._getElement().innerHTML = 'No file chosen'; + this._getElement().innerHTML = `${LOC('import.components.no_file_chosen')}`; } UIUtil.updateStyles(this._getElement(), { @@ -76,4 +77,8 @@ export class FileComponent extends ConfigComponent { isActive: false, }); } + + public override refresh(): void { + this._getElement().innerHTML = `${LOC('import.components.no_file_chosen')}`; + } } diff --git a/src/ui/components/header.ts b/src/ui/components/header.ts index fa6d850..353f4bb 100644 --- a/src/ui/components/header.ts +++ b/src/ui/components/header.ts @@ -23,19 +23,19 @@ export class HeaderComponent extends BaseComponent { .onClick(() => { window.open('https://github.com/LucasDower/ObjToSchematic'); }) - .setTooltip('Open GitHub repo'); + .setTooltip('toolbar.open_github_repo'); this._bugButton = new ToolbarItemComponent({ id: 'bug', iconSVG: AppIcons.BUG }) .onClick(() => { window.open('https://github.com/LucasDower/ObjToSchematic/issues'); }) - .setTooltip('Open GitHub issues'); + .setTooltip('toolbar.open_github_issues'); this._discordButton = new ToolbarItemComponent({ id: 'disc', iconSVG: AppIcons.DISCORD }) .onClick(() => { window.open('https://discord.gg/McS2VrBZPD'); }) - .setTooltip('Open Discord server'); + .setTooltip('toolbar.join_discord'); } // Header element shouldn't be @@ -80,6 +80,10 @@ export class HeaderComponent extends BaseComponent { public refresh() { UIUtil.getElementById('header-desc').innerText = LOC('description'); + + this._githubButton.updateTranslation(); + this._bugButton.updateTranslation(); + this._discordButton.updateTranslation(); } public override registerEvents(): void { diff --git a/src/ui/components/toolbar_item.ts b/src/ui/components/toolbar_item.ts index 4ea8dd6..b779312 100644 --- a/src/ui/components/toolbar_item.ts +++ b/src/ui/components/toolbar_item.ts @@ -1,6 +1,7 @@ import { ASSERT } from '../../util/error_util'; import { UIUtil } from '../../util/ui_util'; import { BaseComponent } from './base'; +import { LOC, TLocalisedKey } from '../../localiser'; export type TToolbarBooleanProperty = 'enabled' | 'active'; @@ -12,10 +13,10 @@ export type TToolbarItemParams = { export class ToolbarItemComponent extends BaseComponent { private _iconSVG: SVGSVGElement; private _label: string; - private _tooltip: string | null; private _onClick?: () => void; private _isActive: boolean; private _grow: boolean; + private _tooltipLocKey: TLocalisedKey | null; public constructor(params: TToolbarItemParams) { super(); @@ -34,7 +35,7 @@ export class ToolbarItemComponent extends BaseComponent { } this._label = ''; - this._tooltip = null; + this._tooltipLocKey = null; } public setGrow() { @@ -42,6 +43,12 @@ export class ToolbarItemComponent extends BaseComponent { return this; } + public updateTranslation() { + if (this._tooltipLocKey) { + UIUtil.getElementById(this._getId() + '-tooltip').innerHTML = LOC(this._tooltipLocKey); + } + } + public setActive(isActive: boolean) { this._isActive = isActive; this._updateStyles(); @@ -92,8 +99,8 @@ export class ToolbarItemComponent extends BaseComponent { return this; } - public setTooltip(text: string) { - this._tooltip = text; + public setTooltip(text: TLocalisedKey) { + this._tooltipLocKey = text; return this; } @@ -105,7 +112,7 @@ export class ToolbarItemComponent extends BaseComponent { `; } else { - if (this._tooltip === null) { + if (this._tooltipLocKey === null) { return `
${this._iconSVG.outerHTML} ${this._label} @@ -115,7 +122,7 @@ export class ToolbarItemComponent extends BaseComponent { return `
${this._iconSVG.outerHTML} ${this._label} - ${this._tooltip} + ${LOC(this._tooltipLocKey)}
`; } diff --git a/src/ui/layout.ts b/src/ui/layout.ts index ed20e14..972de4d 100644 --- a/src/ui/layout.ts +++ b/src/ui/layout.ts @@ -379,7 +379,7 @@ export class UI { .isEnabled(() => { return Renderer.Get.getModelsAvailable() >= MeshType.TriangleMesh; }) - .setTooltip('View mesh'), + .setTooltip('toolbar.view_mesh'), 'voxelMesh': new ToolbarItemComponent({ id: 'voxelMesh', iconSVG: AppIcons.VOXEL }) .onClick(() => { Renderer.Get.setModelToUse(MeshType.VoxelMesh); @@ -390,7 +390,7 @@ export class UI { .isEnabled(() => { return Renderer.Get.getModelsAvailable() >= MeshType.VoxelMesh; }) - .setTooltip('View voxel mesh'), + .setTooltip('toolbar.view_voxel_mesh'), 'blockMesh': new ToolbarItemComponent({ id: 'blockMesh', iconSVG: AppIcons.BLOCK }) .onClick(() => { Renderer.Get.setModelToUse(MeshType.BlockMesh); @@ -401,7 +401,7 @@ export class UI { .isEnabled(() => { return Renderer.Get.getModelsAvailable() >= MeshType.BlockMesh; }) - .setTooltip('View block mesh'), + .setTooltip('toolbar.view_block_mesh'), }, componentOrder: ['mesh', 'voxelMesh', 'blockMesh'], }, @@ -417,7 +417,7 @@ export class UI { .isEnabled(() => { return Renderer.Get.getActiveMeshType() !== MeshType.None; }) - .setTooltip('Toggle grid'), + .setTooltip('toolbar.toggle_grid'), 'axes': new ToolbarItemComponent({ id: 'axes', iconSVG: AppIcons.AXES }) .onClick(() => { Renderer.Get.toggleIsAxesEnabled(); @@ -425,7 +425,7 @@ export class UI { .isActive(() => { return Renderer.Get.isAxesEnabled(); }) - .setTooltip('Toggle axes'), + .setTooltip('toolbar.toggle_axes'), 'night-vision': new ToolbarItemComponent({ id: 'night', iconSVG: AppIcons.BULB }) .onClick(() => { Renderer.Get.toggleIsNightVisionEnabled(); @@ -436,7 +436,7 @@ export class UI { .isEnabled(() => { return Renderer.Get.canToggleNightVision(); }) - .setTooltip('Toggle night vision'), + .setTooltip('toolbar.toggle_night_vision'), }, componentOrder: ['grid', 'axes', 'night-vision'], }, @@ -452,7 +452,7 @@ export class UI { .isActive(() => { return Renderer.Get.isSliceViewerEnabled(); }) - .setTooltip('Toggle slice viewer'), + .setTooltip('toolbar.toggle_slice_viewer'), 'plus': new ToolbarItemComponent({ id: 'plus', iconSVG: AppIcons.PLUS }) .onClick(() => { Renderer.Get.incrementSliceHeight(); @@ -461,7 +461,7 @@ export class UI { return Renderer.Get.isSliceViewerEnabled() && Renderer.Get.canIncrementSliceHeight(); }) - .setTooltip('Decrement slice'), + .setTooltip('toolbar.decrement_slice'), 'minus': new ToolbarItemComponent({ id: 'minus', iconSVG: AppIcons.MINUS }) .onClick(() => { Renderer.Get.decrementSliceHeight(); @@ -470,7 +470,7 @@ export class UI { return Renderer.Get.isSliceViewerEnabled() && Renderer.Get.canDecrementSliceHeight(); }) - .setTooltip('Increment slice'), + .setTooltip('toolbar.increment_slice'), }, componentOrder: ['slice', 'plus', 'minus'], }, @@ -486,17 +486,17 @@ export class UI { .onClick(() => { ArcballCamera.Get.onZoomOut(); }) - .setTooltip('Zoom out'), + .setTooltip('toolbar.zoom_out'), 'zoomIn': new ToolbarItemComponent({ id: 'zin', iconSVG: AppIcons.PLUS }) .onClick(() => { ArcballCamera.Get.onZoomIn(); }) - .setTooltip('Zoom in'), + .setTooltip('toolbar.zoom_in'), 'reset': new ToolbarItemComponent({ id: 'reset', iconSVG: AppIcons.CENTRE }) .onClick(() => { ArcballCamera.Get.reset(); }) - .setTooltip('Reset camera'), + .setTooltip('toolbar.reset_camera'), }, componentOrder: ['zoomOut', 'zoomIn', 'reset'], }, @@ -509,7 +509,7 @@ export class UI { .isActive(() => { return ArcballCamera.Get.isPerspective(); }) - .setTooltip('Perspective camera'), + .setTooltip('toolbar.perspective_camera'), 'orthographic': new ToolbarItemComponent({ id: 'orth', iconSVG: AppIcons.ORTHOGRAPHIC }) .onClick(() => { ArcballCamera.Get.setCameraMode('orthographic'); @@ -517,7 +517,7 @@ export class UI { .isActive(() => { return ArcballCamera.Get.isOrthographic(); }) - .setTooltip('Orthographic camera'), + .setTooltip('toolbar.orthographic_camera'), }, componentOrder: ['perspective', 'orthographic'], }, @@ -679,6 +679,20 @@ export class UI { private _handleLanguageChange() { HeaderComponent.Get.refresh(); + + Object.values(this._toolbarLeft.groups).forEach((group) => { + Object.values(group.components).forEach((comp) => { + comp.updateTranslation(); + }); + }); + + Object.values(this._toolbarRight.groups).forEach((group) => { + Object.values(group.components).forEach((comp) => { + comp.updateTranslation(); + }); + }); + + for (let i = 0; i < EAction.MAX; ++i) { const group = this._getGroup(i); const header = UIUtil.getElementById(`component_header_${group.id}`);