Skip to content

Commit 086ddd6

Browse files
committed
use rust-i18n for translations
1 parent d76a74b commit 086ddd6

10 files changed

+273
-168
lines changed

Cargo.lock

+226-12
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -73,3 +73,4 @@ rfd = "0.14.1"
7373
futures-lite = "2.3.0"
7474
anyhow = "1.0.83"
7575
egui-toast = "0.13.0"
76+
rust-i18n = "3.0.1"

lang/en_us.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
menu_bar:
22
file:
3-
.: File
3+
title: File
44
quit: Quit
55
save: Save
66

lang/zh_cn.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
menu_bar:
22
file:
3-
.: 文件
3+
title: 文件
44
quit: 退出
55
save: 保存
66

src/main.rs

+19-21
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ mod selection;
1616
mod serialzation;
1717
mod tab;
1818
mod timing;
19-
mod translation;
2019
mod widgets;
2120

2221
use crate::assets::AssetsPlugin;
@@ -42,14 +41,15 @@ use crate::tab::timeline::{TimelineTabPlugin, TimelineViewport};
4241
use crate::tab::TabPlugin;
4342
use crate::tab::{EditorTab, TabRegistry};
4443
use crate::timing::TimingPlugin;
45-
use crate::translation::{TranslationPlugin, Translator};
4644
use bevy::diagnostic::{DiagnosticsStore, FrameTimeDiagnosticsPlugin};
47-
use bevy::ecs::system::SystemState;
4845
use bevy::prelude::*;
4946
use bevy_egui::egui::{Color32, Frame};
5047
use bevy_egui::{EguiContext, EguiPlugin};
5148
use bevy_mod_picking::prelude::*;
5249
use egui_dock::{DockArea, DockState, NodeIndex, Style};
50+
use rust_i18n::{i18n, t};
51+
52+
i18n!("lang", fallback = "en_us");
5353

5454
fn main() {
5555
App::new()
@@ -71,7 +71,6 @@ fn main() {
7171
.add_plugins(EditingPlugin)
7272
.add_plugins(FrameTimeDiagnosticsPlugin)
7373
.add_plugins(AssetsPlugin)
74-
.add_plugins(TranslationPlugin)
7574
.add_plugins(NotificationPlugin)
7675
.add_plugins(FilePickingPlugin)
7776
.add_systems(Startup, setup_egui_image_loader_system)
@@ -125,7 +124,7 @@ fn setup_egui_font_system(
125124
font_def
126125
.families
127126
.get_mut(&font_family)
128-
.expect("Failed to setuo font")
127+
.expect("Failed to setup font")
129128
.insert(0, font_name);
130129

131130
ctx.set_fonts(font_def);
@@ -176,13 +175,10 @@ impl egui_dock::TabViewer for TabViewer<'_> {
176175
type Tab = EditorTab;
177176

178177
fn title(&mut self, tab: &mut Self::Tab) -> egui::WidgetText {
179-
let mut system_state: SystemState<Translator> = SystemState::new(self.world);
180-
let translator = system_state.get(self.world);
181-
182178
self.registry
183179
.get(tab)
184-
.map(|t| translator.tr(t.title()))
185-
.unwrap_or("Unknown".to_string())
180+
.map(|t| t!(t.title()))
181+
.unwrap_or("Unknown".into())
186182
.into()
187183
}
188184

@@ -248,16 +244,10 @@ fn ui_system(world: &mut World) {
248244
fps = value;
249245
}
250246

251-
let mut system_state: SystemState<Translator> = SystemState::new(world);
252-
let translator = system_state.get(world);
253-
let file = translator.tr("menu_bar.file");
254-
let save = translator.tr("menu_bar.file.save");
255-
let quit = translator.tr("menu_bar.file.quit");
256-
257247
egui::TopBottomPanel::top("phichain.MenuBar").show(ctx, |ui| {
258248
egui::menu::bar(ui, |ui| {
259-
ui.menu_button(file, |ui| {
260-
if ui.button(save).clicked() {
249+
ui.menu_button(t!("menu_bar.file.title"), |ui| {
250+
if ui.button(t!("menu_bar.file.save")).clicked() {
261251
if let Ok(chart) = PhiChainExporter::export(world) {
262252
let project = world.resource::<Project>();
263253
let result = std::fs::write(project.root_dir.join("chart.json"), chart);
@@ -273,16 +263,24 @@ fn ui_system(world: &mut World) {
273263
}
274264
}
275265
ui.separator();
276-
if ui.button(quit).clicked() {
266+
if ui.button(t!("menu_bar.file.quit")).clicked() {
277267
std::process::exit(0);
278268
}
279269
});
280270
ui.menu_button("Tabs", |ui| {
281271
world.resource_scope(|world, mut ui_state: Mut<UiState>| {
282272
world.resource_scope(|_, registry: Mut<TabRegistry>| {
283273
for (tab, registered_tab) in registry.iter() {
284-
let opened = ui_state.state.iter_all_tabs().map(|x| x.1).collect::<Vec<_>>().contains(&tab);
285-
if ui.selectable_label(opened, registered_tab.title()).clicked() {
274+
let opened = ui_state
275+
.state
276+
.iter_all_tabs()
277+
.map(|x| x.1)
278+
.collect::<Vec<_>>()
279+
.contains(&tab);
280+
if ui
281+
.selectable_label(opened, t!(registered_tab.title()))
282+
.clicked()
283+
{
286284
if opened {
287285
if let Some(node) = ui_state.state.find_tab(tab) {
288286
ui_state.state.remove_tab(node);

src/tab/audio_setting.rs

+4-9
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,23 @@
11
use crate::audio::AudioSettings;
22
use bevy::prelude::*;
33
use egui::Ui;
4+
use rust_i18n::t;
45

5-
use crate::translation::Translator;
6-
7-
pub fn audio_setting_tab(
8-
In(ui): In<&mut Ui>,
9-
mut audio_settings: ResMut<AudioSettings>,
10-
translator: Translator,
11-
) {
6+
pub fn audio_setting_tab(In(ui): In<&mut Ui>, mut audio_settings: ResMut<AudioSettings>) {
127
egui::Grid::new("audio_setting_grid")
138
.num_columns(2)
149
.spacing([40.0, 2.0])
1510
.striped(true)
1611
.show(ui, |ui| {
17-
ui.label(translator.tr("tab.audio_setting.music_volume"));
12+
ui.label(t!("tab.audio_setting.music_volume"));
1813
ui.add(
1914
egui::DragValue::new(&mut audio_settings.music_volume)
2015
.clamp_range(0.00..=1.2)
2116
.speed(0.01),
2217
);
2318
ui.end_row();
2419

25-
ui.label(translator.tr("tab.audio_setting.hit_sound_volume"));
20+
ui.label(t!("tab.audio_setting.hit_sound_volume"));
2621
ui.add(
2722
egui::DragValue::new(&mut audio_settings.hit_sound_volume)
2823
.clamp_range(0.00..=1.2)

src/tab/chart_basic_setting.rs

+3-8
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,15 @@
11
use crate::audio::Offset;
22
use bevy::prelude::*;
33
use egui::Ui;
4+
use rust_i18n::t;
45

5-
use crate::translation::Translator;
6-
7-
pub fn chart_basic_setting_tab(
8-
In(ui): In<&mut Ui>,
9-
mut offset: ResMut<Offset>,
10-
translator: Translator,
11-
) {
6+
pub fn chart_basic_setting_tab(In(ui): In<&mut Ui>, mut offset: ResMut<Offset>) {
127
egui::Grid::new("chart_basic_setting_grid")
138
.num_columns(2)
149
.spacing([40.0, 2.0])
1510
.striped(true)
1611
.show(ui, |ui| {
17-
ui.label(translator.tr("tab.chart_basic_setting.offset"));
12+
ui.label(t!("tab.chart_basic_setting.offset"));
1813
ui.add(egui::DragValue::new(&mut offset.0).speed(1));
1914
ui.end_row();
2015
});

src/tab/inspector.rs

+13-14
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use bevy::prelude::*;
22
use egui::Ui;
33
use num::Rational32;
4+
use rust_i18n::t;
45

56
use crate::chart::event::{LineEvent, LineEventKind};
67
use crate::{
@@ -9,23 +10,21 @@ use crate::{
910
note::{Note, NoteKind},
1011
},
1112
selection::Selected,
12-
translation::Translator,
1313
};
1414

1515
pub fn inspector_ui_system(
1616
In(ui): In<&mut Ui>,
1717
mut selected_notes: Query<&mut Note, With<Selected>>,
1818
mut selected_events: Query<&mut LineEvent, With<Selected>>,
19-
translator: Translator,
2019
) {
2120
let mut selected_notes: Vec<_> = selected_notes.iter_mut().collect();
2221
let mut selected_events: Vec<_> = selected_events.iter_mut().collect();
2322
if selected_notes.len() == 1 && selected_events.is_empty() {
2423
let selected_note = selected_notes.get_mut(0).unwrap();
25-
single_note_inspector(ui, selected_note, &translator);
24+
single_note_inspector(ui, selected_note);
2625
} else if selected_notes.is_empty() && selected_events.len() == 1 {
2726
let selected_event = selected_events.get_mut(0).unwrap();
28-
single_event_inspector(ui, selected_event, &translator);
27+
single_event_inspector(ui, selected_event);
2928
}
3029
}
3130

@@ -62,21 +61,21 @@ impl BeatExt for Ui {
6261
}
6362
}
6463

65-
fn single_event_inspector(ui: &mut Ui, event: &mut LineEvent, translator: &Translator) {
64+
fn single_event_inspector(ui: &mut Ui, event: &mut LineEvent) {
6665
egui::Grid::new("inspector_grid")
6766
.num_columns(2)
6867
.spacing([40.0, 2.0])
6968
.striped(true)
7069
.show(ui, |ui| {
71-
ui.label(translator.tr("tab.inspector.single_event.start_beat"));
70+
ui.label(t!("tab.inspector.single_event.start_beat"));
7271
ui.beat(&mut event.start_beat);
7372
ui.end_row();
7473

75-
ui.label(translator.tr("tab.inspector.single_event.end_beat"));
74+
ui.label(t!("tab.inspector.single_event.end_beat"));
7675
ui.beat(&mut event.end_beat);
7776
ui.end_row();
7877

79-
ui.label(translator.tr("tab.inspector.single_event.start_value"));
78+
ui.label(t!("tab.inspector.single_event.start_value"));
8079
let range = match event.kind {
8180
LineEventKind::Opacity => 0.0..=255.0,
8281
_ => f32::MIN..=f32::MAX,
@@ -88,7 +87,7 @@ fn single_event_inspector(ui: &mut Ui, event: &mut LineEvent, translator: &Trans
8887
);
8988
ui.end_row();
9089

91-
ui.label(translator.tr("tab.inspector.single_event.end_value"));
90+
ui.label(t!("tab.inspector.single_event.end_value"));
9291
ui.add(
9392
egui::DragValue::new(&mut event.end)
9493
.clamp_range(range.clone())
@@ -98,22 +97,22 @@ fn single_event_inspector(ui: &mut Ui, event: &mut LineEvent, translator: &Trans
9897
});
9998
}
10099

101-
fn single_note_inspector(ui: &mut Ui, note: &mut Note, translator: &Translator) {
100+
fn single_note_inspector(ui: &mut Ui, note: &mut Note) {
102101
egui::Grid::new("inspector_grid")
103102
.num_columns(2)
104103
.spacing([40.0, 2.0])
105104
.striped(true)
106105
.show(ui, |ui| {
107-
ui.label(translator.tr("tab.inspector.single_note.x"));
106+
ui.label(t!("tab.inspector.single_note.x"));
108107
ui.add(egui::DragValue::new(&mut note.x).speed(1));
109108
ui.end_row();
110109

111-
ui.label(translator.tr("tab.inspector.single_note.beat"));
110+
ui.label(t!("tab.inspector.single_note.beat"));
112111
ui.beat(&mut note.beat);
113112
ui.end_row();
114113

115114
if let NoteKind::Hold { hold_beat } = note.kind {
116-
ui.label(translator.tr("tab.inspector.single_note.hold_beat"));
115+
ui.label(t!("tab.inspector.single_note.hold_beat"));
117116

118117
let mut bind = hold_beat;
119118
ui.beat(&mut bind);
@@ -124,7 +123,7 @@ fn single_note_inspector(ui: &mut Ui, note: &mut Note, translator: &Translator)
124123
ui.end_row();
125124
}
126125

127-
ui.label(translator.tr("tab.inspector.single_note.above"));
126+
ui.label(t!("tab.inspector.single_note.above"));
128127
ui.checkbox(&mut note.above, "");
129128
});
130129
}

src/tab/timeline_setting.rs

+5-10
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,32 @@
11
use bevy::prelude::*;
22
use egui::Ui;
3-
4-
use crate::translation::Translator;
3+
use rust_i18n::t;
54

65
use super::timeline::TimelineSettings;
76

8-
pub fn timeline_setting_tab(
9-
In(ui): In<&mut Ui>,
10-
mut timeline_settings: ResMut<TimelineSettings>,
11-
translator: Translator,
12-
) {
7+
pub fn timeline_setting_tab(In(ui): In<&mut Ui>, mut timeline_settings: ResMut<TimelineSettings>) {
138
egui::Grid::new("timeline_setting_grid")
149
.num_columns(2)
1510
.spacing([40.0, 2.0])
1611
.striped(true)
1712
.show(ui, |ui| {
18-
ui.label(translator.tr("tab.timeline_setting.zoom"));
13+
ui.label(t!("tab.timeline_setting.zoom"));
1914
ui.add(
2015
egui::DragValue::new(&mut timeline_settings.zoom)
2116
.clamp_range(0.1..=f32::MAX)
2217
.speed(0.01),
2318
);
2419
ui.end_row();
2520

26-
ui.label(translator.tr("tab.timeline_setting.density"));
21+
ui.label(t!("tab.timeline_setting.density"));
2722
ui.add(
2823
egui::DragValue::new(&mut timeline_settings.density)
2924
.clamp_range(1..=32)
3025
.speed(1),
3126
);
3227
ui.end_row();
3328

34-
ui.label(translator.tr("tab.timeline_setting.lane"));
29+
ui.label(t!("tab.timeline_setting.lane"));
3530
ui.add(
3631
egui::DragValue::new(&mut timeline_settings.lanes)
3732
.clamp_range(1..=32)

0 commit comments

Comments
 (0)