diff --git a/wayvr/src/assets/lang/de.json b/wayvr/src/assets/lang/de.json index bcdb30ac..f4969b8c 100644 --- a/wayvr/src/assets/lang/de.json +++ b/wayvr/src/assets/lang/de.json @@ -109,9 +109,10 @@ "LAST_EXISTING_SET": "Dies ist das letzte vorhandene Set.", "EMPTY_SET": "Leeres Set!", "LETS_ADD_OVERLAYS": "Lass uns ein paar Overlays von der Uhr hinzufügen!", - "FIXING_FLOOR": "Boden wird in 5 Sekunden fixiert...", "ONE_CONTROLLER_ON_FLOOR": "Lege einen Controller auf den Boden!", "CANNOT_ADD_SET": "Satz kann nicht hinzugefügt werden!", - "MAXIMUM_SETS_REACHED": "Maximale Anzahl an Sets erreicht." - } + "MAXIMUM_SETS_REACHED": "Maximale Anzahl an Sets erreicht.", + "FIXING_FLOOR_IN_X_SECS": "Boden wird in {SECONDS} Sekunde(n) repariert..." + }, + "DONE": "Erledigt" } \ No newline at end of file diff --git a/wayvr/src/assets/lang/en.json b/wayvr/src/assets/lang/en.json index 2c176feb..b3a3070a 100644 --- a/wayvr/src/assets/lang/en.json +++ b/wayvr/src/assets/lang/en.json @@ -4,41 +4,56 @@ }, "BAR": { "ADD_MIRROR": "Add a new mirror overlay", - "EDIT_MODE_TOGGLE": "Toggle edit mode", "ADD_NEW_SET": "Add new set", - "DELETE_CURRENT_SET": "Delete current set", - "TOGGLE_VISIBILITY": "Toggle visibility", - "RESET_POSITION": "Reset position", - "RELOAD_FROM_DISK": "Reload XML from disk", - "CLOSE_MIRROR": "Close mirror", "CLOSE_APP": "Close app", + "CLOSE_MIRROR": "Close mirror", + "DELETE_CURRENT_SET": "Delete current set", + "EDIT_MODE_TOGGLE": "Toggle edit mode", "FORCE_CLOSE_APP": "Force close app", "HANDSFREE": { - "TITLE": "Handsfree mode", - "NONE": "Off", - "HMD": "HMD + pinch", + "EYE_ONLY": "Eye only", "EYE_TRACKING": "Eye + pinch", + "HMD": "HMD + pinch", "HMD_ONLY": "HMD only", - "EYE_ONLY": "Eye only" - } + "NONE": "Off", + "TITLE": "Handsfree mode" + }, + "RELOAD_FROM_DISK": "Reload XML from disk", + "RESET_POSITION": "Reset position", + "TOGGLE_VISIBILITY": "Toggle visibility" }, "DEFAULT": "Default", "DISABLED": "Disabled", + "DONE": "Done", "EDIT_MODE": { "ADJUST_CURVATURE": "Adjust curvature", + "ALIGN_TO_HMD": "Align to HMD", "ALPHA_BLEND_MODE": "Alpha blend mode", - "BLENDING_ADDITIVE": "Additive blending", "ANGLE_FADE": "Angle fade", "ANGLE_FADE_HELP": "Fade when not facing HMD", + "BLENDING_ADDITIVE": "Additive blending", + "BLOCK_INPUT": "Block game input", "CURVATURE": "Curvature", "DELETE": "Long press to remove from current set", "DISABLE_GRAB": "Disable grab", + "GLOBAL": "Always visible", "HINT_POINT_WINDOW": "Point at a window to change its parameters.\nOnce done, leave edit mode using the button on the right.", "INTERPOLATION": "Interpolation", - "ALIGN_TO_HMD": "Align to HMD", "KEYBOARD": "Keyboard", "LEAVE": "Leave edit mode", "LOCK_INTERACTION": "Lock interaction", + "MOUSE": { + "FLIP180": "Flipped 180°", + "FLIP270": "Flipped 270°", + "FLIP90": "Flipped 90°", + "FLIPPED": "Flipped", + "NORMAL": "Normal", + "ROTATE180": "Rotated 180°", + "ROTATE270": "Rotated 270°", + "ROTATE90": "Rotated 90°", + "TITLE": "Mouse fixes", + "WRONG_SCREEN_SELECTION_HELP": "If the cursor moves on a completely different screen,\nthe screens were likely selected wrong. See readme." + }, "MOVE_PRESS_AND_DRAG": "Move (press & drag)", "OPACITY": "Opacity", "POS_ANCHORED": "Anchored: Moves with center marker. Default.", @@ -48,56 +63,42 @@ "POS_HMD": "Follow the HMD.", "POS_STATIC": "Static: Not part of any set, no recenter.", "POSITIONING": "Positioning", - "GLOBAL": "Always visible", - "BLOCK_INPUT": "Block game input", "RESIZE_PRESS_AND_DRAG": "Resize (press & drag)", "STEREO_3D_MODE": { "ADJUST_MOUSE": "Adjust mouse", + "FULL_FRAME": "Full 3D", + "FULL_FRAME_BAT": "Full-BAT", + "FULL_FRAME_SBS": "Full-SBS", + "FULL_FRAME_TAB": "Full-TAB", "SPLIT_BOTTOM_TOP": "BOTTOM→TOP", "SPLIT_LEFT_RIGHT": "LEFT→RIGHT", "SPLIT_RIGHT_LEFT": "RIGHT→LEFT", "SPLIT_TOP_BOTTOM": "TOP→BOTTOM", - "TITLE": "3D Stereo Mode", - "FULL_FRAME": "Full 3D", - "FULL_FRAME_SBS": "Full-SBS", - "FULL_FRAME_TAB": "Full-TAB", - "FULL_FRAME_BAT": "Full-BAT" - }, - "MOUSE": { - "TITLE": "Mouse fixes", - "WRONG_SCREEN_SELECTION_HELP": "If the cursor moves on a completely different screen,\nthe screens were likely selected wrong. See readme.", - "NORMAL": "Normal", - "ROTATE90": "Rotated 90°", - "ROTATE180": "Rotated 180°", - "ROTATE270": "Rotated 270°", - "FLIPPED": "Flipped", - "FLIP90": "Flipped 90°", - "FLIP180": "Flipped 180°", - "FLIP270": "Flipped 270°" + "TITLE": "3D Stereo Mode" } }, "GRAB": { "ADJUST_DISTANCE": "Adjust distance", "ADJUST_SIZE": "Adjust size", - "UNRESTRICTED_MOVEMENT": "Unrestricted movement", - "GRABBING_WATCH": "To swap hands, move the watch in front and grab it with the other hand.", - "GRABBING_STATIC": "This overlay is Static and will stay in place, ignoring recenter.", "GRABBING_ANCHORED": "Anchored overlays all move together. Separate a single window by grabbing it with the other hand while still grabbing the anchor.", "GRABBING_ANCHORED_EDIT": "This overlay will stay anchored to the center marker.", "GRABBING_FLOATING": "This overlay is Floating and will stay in place, unless recentered.", - "GRABBING_FOLLOW": "This overlay will follow the device it is attached to." + "GRABBING_FOLLOW": "This overlay will follow the device it is attached to.", + "GRABBING_STATIC": "This overlay is Static and will stay in place, ignoring recenter.", + "GRABBING_WATCH": "To swap hands, move the watch in front and grab it with the other hand.", + "UNRESTRICTED_MOVEMENT": "Unrestricted movement" }, "TOAST": { - "DEFAULT_TITLE": "Notification", - "ERROR": "Error", "CANNOT_ADD_SET": "Cannot add set!", - "MAXIMUM_SETS_REACHED": "Maximum number of sets reached.", "CANNOT_REMOVE_SET": "Cannot remove set!", - "NO_SET_SELECTED": "No set is selected.", - "LAST_EXISTING_SET": "This is the last existing set.", + "DEFAULT_TITLE": "Notification", "EMPTY_SET": "Empty set!", + "ERROR": "Error", + "FIXING_FLOOR_IN_X_SECS": "Fixing floor in {SECONDS} second(s)...", + "LAST_EXISTING_SET": "This is the last existing set.", "LETS_ADD_OVERLAYS": "Let's add some overlays from the watch!", - "FIXING_FLOOR": "Fixing floor in 5 seconds...", + "MAXIMUM_SETS_REACHED": "Maximum number of sets reached.", + "NO_SET_SELECTED": "No set is selected.", "ONE_CONTROLLER_ON_FLOOR": "Place one controller on the floor!" }, "WATCH": { diff --git a/wayvr/src/assets/lang/es.json b/wayvr/src/assets/lang/es.json index 6dc279c2..8236a64a 100644 --- a/wayvr/src/assets/lang/es.json +++ b/wayvr/src/assets/lang/es.json @@ -109,9 +109,10 @@ "LAST_EXISTING_SET": "Este es el último conjunto existente.", "EMPTY_SET": "¡Conjunto vacío!", "LETS_ADD_OVERLAYS": "¡Añadamos algunos overlays desde el reloj!", - "FIXING_FLOOR": "Fijando el suelo en 5 segundos...", "ONE_CONTROLLER_ON_FLOOR": "¡Coloca un mando en el suelo!", "CANNOT_ADD_SET": "¡No se puede agregar el conjunto!", - "MAXIMUM_SETS_REACHED": "Se ha alcanzado el número máximo de sets." - } + "MAXIMUM_SETS_REACHED": "Se ha alcanzado el número máximo de sets.", + "FIXING_FLOOR_IN_X_SECS": "Corrigiendo el suelo en {SECONDS} segundo(s)..." + }, + "DONE": "Hecho" } \ No newline at end of file diff --git a/wayvr/src/assets/lang/it.json b/wayvr/src/assets/lang/it.json index f21ea3b9..ed3015e8 100644 --- a/wayvr/src/assets/lang/it.json +++ b/wayvr/src/assets/lang/it.json @@ -97,8 +97,8 @@ "LAST_EXISTING_SET": "Questo è l'ultimo set esistente.", "EMPTY_SET": "Set vuoto!", "LETS_ADD_OVERLAYS": "Aggiungiamo degli overlay dal Watch!", - "FIXING_FLOOR": "Rifissaggio del pavimento tra 5 secondi...", - "ONE_CONTROLLER_ON_FLOOR": "Posiziona un controller a terra!" + "ONE_CONTROLLER_ON_FLOOR": "Posiziona un controller a terra!", + "FIXING_FLOOR_IN_X_SECS": "Correzione del pavimento in {SECONDS} secondo/i..." }, "WATCH": { "ADD_NEW_SET": "Aggiungi un nuovo set", @@ -111,5 +111,6 @@ "RECENTER": "Recentra l'area di gioco", "SWITCH_TO_SET": "Passa a set", "TOGGLE_FOR_CURRENT_SET": "Attiva/disattiva per il set corrente" - } + }, + "DONE": "Fatto" } \ No newline at end of file diff --git a/wayvr/src/assets/lang/ja.json b/wayvr/src/assets/lang/ja.json index 111fddc5..c493120a 100644 --- a/wayvr/src/assets/lang/ja.json +++ b/wayvr/src/assets/lang/ja.json @@ -107,9 +107,10 @@ "LAST_EXISTING_SET": "これが最後の設定です。", "EMPTY_SET": "空のセットです!", "LETS_ADD_OVERLAYS": "ウォッチからオーバーレイを追加しましょう!", - "FIXING_FLOOR": "5秒後にフロアを固定します...", "ONE_CONTROLLER_ON_FLOOR": "コントローラーを床に置いてください!", "CANNOT_ADD_SET": "セットを追加できません!", - "MAXIMUM_SETS_REACHED": "最大セット数に達しました。" - } + "MAXIMUM_SETS_REACHED": "最大セット数に達しました。", + "FIXING_FLOOR_IN_X_SECS": "{SECONDS}秒で床を固定中..." + }, + "DONE": "完了" } \ No newline at end of file diff --git a/wayvr/src/assets/lang/pl.json b/wayvr/src/assets/lang/pl.json index d69cd719..0d3d1fca 100644 --- a/wayvr/src/assets/lang/pl.json +++ b/wayvr/src/assets/lang/pl.json @@ -107,9 +107,10 @@ "LAST_EXISTING_SET": "To jest ostatni istniejący zestaw.", "EMPTY_SET": "Pusty zestaw!", "LETS_ADD_OVERLAYS": "Dodajmy kilka nakładek z zegarka!", - "FIXING_FLOOR": "Naprawianie podłogi za 5 sekund...", "ONE_CONTROLLER_ON_FLOOR": "Umieść jeden kontroler na podłodze!", "CANNOT_ADD_SET": "Nie można dodać zestawu!", - "MAXIMUM_SETS_REACHED": "Osiągnięto maksymalną liczbę zestawów." - } + "MAXIMUM_SETS_REACHED": "Osiągnięto maksymalną liczbę zestawów.", + "FIXING_FLOOR_IN_X_SECS": "Naprawianie podłogi za {SECONDS} sekund(y)..." + }, + "DONE": "Gotowe" } \ No newline at end of file diff --git a/wayvr/src/assets/lang/zh_CN.json b/wayvr/src/assets/lang/zh_CN.json index 87ff1f5c..eda4e52a 100644 --- a/wayvr/src/assets/lang/zh_CN.json +++ b/wayvr/src/assets/lang/zh_CN.json @@ -97,8 +97,8 @@ "LAST_EXISTING_SET": "这是最后一个现有的集合。", "EMPTY_SET": "空集合!", "LETS_ADD_OVERLAYS": "让我们从手表添加一些覆盖层吧!", - "FIXING_FLOOR": "将在 5 秒内修复地面...", - "ONE_CONTROLLER_ON_FLOOR": "请将一个控制器放在地面上!" + "ONE_CONTROLLER_ON_FLOOR": "请将一个控制器放在地面上!", + "FIXING_FLOOR_IN_X_SECS": "{SECONDS}秒内固定地面..." }, "WATCH": { "ADD_NEW_SET": "添加新集合", @@ -111,5 +111,6 @@ "RECENTER": "重置游玩区中心 (Recenter)", "SWITCH_TO_SET": "切换到集合", "TOGGLE_FOR_CURRENT_SET": "切换当前集合" - } + }, + "DONE": "完成" } \ No newline at end of file diff --git a/wayvr/src/gui/panel/button.rs b/wayvr/src/gui/panel/button.rs index ab14b660..ad4e9689 100644 --- a/wayvr/src/gui/panel/button.rs +++ b/wayvr/src/gui/panel/button.rs @@ -577,19 +577,37 @@ pub(super) fn setup_custom_button( return Ok(EventResult::Pass); } - Toast::new( - ToastTopic::System, - "TOAST.FIXING_FLOOR".into(), - "TOAST.ONE_CONTROLLER_ON_FLOOR".into(), - ) - .with_timeout(5.) - .with_sound(true) - .submit(app); + let globals = app.wgui_globals.clone(); - app.tasks.enqueue_at( - TaskType::Playspace(PlayspaceTask::FixFloor), - Instant::now() + Duration::from_secs(5), - ); + let duration_secs = 5; + let now = Instant::now(); + + for i in 0..duration_secs { + Toast::new( + ToastTopic::System, + globals.i18n().translate_and_replace( + "TOAST.FIXING_FLOOR_IN_X_SECS", + ("{SECONDS}", &format!("{}", duration_secs - i)), + ), + "TOAST.ONE_CONTROLLER_ON_FLOOR".into(), + ) + .with_timeout(1.0) + .with_lerp_amount(1.0) + .with_sound(i == 0) + .submit_at(app, now + Duration::from_secs(i as _)); + } + + app.audio_sample_player + .play_sample(&mut app.audio_system, "fix_floor"); + + let deadline = now + Duration::from_secs(duration_secs); + + app.tasks + .enqueue_at(TaskType::Playspace(PlayspaceTask::FixFloor), deadline); + + Toast::new(ToastTopic::System, "DONE".into(), String::new()) + .with_timeout(2.0) + .submit_at(app, deadline); Ok(EventResult::Consumed) }), "::Shutdown" => Box::new(move |_common, data, app, _| { diff --git a/wayvr/src/overlays/toast.rs b/wayvr/src/overlays/toast.rs index 7db4fb48..410a54a3 100644 --- a/wayvr/src/overlays/toast.rs +++ b/wayvr/src/overlays/toast.rs @@ -30,6 +30,7 @@ pub struct Toast { pub body: String, pub opacity: f32, pub timeout: f32, + pub lerp_amount: f32, pub sound: bool, pub topic: ToastTopic, } @@ -41,6 +42,7 @@ impl Toast { title, body, opacity: 1.0, + lerp_amount: 0.1, timeout: 3.0, sound: false, topic, @@ -50,6 +52,10 @@ impl Toast { self.timeout = timeout; self } + pub const fn with_lerp_amount(mut self, lerp: f32) -> Self { + self.lerp_amount = lerp; + self + } pub const fn with_opacity(mut self, opacity: f32) -> Self { self.opacity = opacity; self @@ -118,7 +124,9 @@ fn new_toast(toast: Toast, app: &mut AppState) -> Option { ToastDisplayMethod::Center => ( vec3(0., -0.2, -0.5), Quat::IDENTITY, - Positioning::FollowHead { lerp: 0.1 }, + Positioning::FollowHead { + lerp: toast.lerp_amount, + }, ), ToastDisplayMethod::Watch => { let relative_to = Positioning::FollowHand { diff --git a/wayvr/src/res/fix_floor.mp3 b/wayvr/src/res/fix_floor.mp3 new file mode 100644 index 00000000..8a2cf9c6 Binary files /dev/null and b/wayvr/src/res/fix_floor.mp3 differ diff --git a/wayvr/src/state.rs b/wayvr/src/state.rs index 59146f36..180f14dd 100644 --- a/wayvr/src/state.rs +++ b/wayvr/src/state.rs @@ -98,7 +98,7 @@ impl AppState { let mut audio_sample_player = audio::SamplePlayer::new(); audio_sample_player.register_sample( "key_click", - audio::AudioSample::from_mp3(&*audio::AudioSample::bytes_from_config_or_default( + audio::AudioSample::from_mp3(&audio::AudioSample::bytes_from_config_or_default( "sound/key_click.mp3", include_bytes!("res/key_click.mp3"), ))?, @@ -106,12 +106,20 @@ impl AppState { audio_sample_player.register_sample( "toast", - audio::AudioSample::from_mp3(&*audio::AudioSample::bytes_from_config_or_default( + audio::AudioSample::from_mp3(&audio::AudioSample::bytes_from_config_or_default( "sound/toast.mp3", include_bytes!("res/toast.mp3"), ))?, )?; + audio_sample_player.register_sample( + "fix_floor", + audio::AudioSample::from_mp3(&audio::AudioSample::bytes_from_config_or_default( + "sound/fix_floor.mp3", + include_bytes!("res/fix_floor.mp3"), + ))?, + )?; + let mut assets = Box::new(gui::asset::GuiAsset {}); audio_sample_player.register_wgui_samples(assets.as_mut())?;