checkbox sounds, app launch sounds

This commit is contained in:
Aleksander
2026-01-06 17:09:39 +01:00
parent 46ab3ce960
commit 51dbb6f14d
13 changed files with 85 additions and 24 deletions

View File

@@ -60,6 +60,7 @@ pub struct Frontend<T> {
popup_manager: PopupManager,
toast_manager: ToastManager,
timestep: Timestep,
sounds_to_play: Vec<SoundType>,
window_audio_settings: WguiWindow,
view_audio_settings: Option<views::audio_settings::View>,
@@ -72,11 +73,22 @@ pub struct FrontendUpdateParams<'a, T> {
pub timestep_alpha: f32,
}
pub struct FrontendUpdateResult {
pub layout_result: LayoutUpdateResult,
pub sounds_to_play: Vec<SoundType>,
}
pub struct InitParams<T> {
pub settings: Box<dyn settings::SettingsIO>,
pub interface: BoxDashInterface<T>,
}
#[derive(Clone)]
pub enum SoundType {
Startup,
Launch,
}
#[derive(Clone)]
pub enum FrontendTask {
SetTab(TabType),
@@ -88,6 +100,7 @@ pub enum FrontendTask {
UpdateAudioSettingsView,
RecenterPlayspace,
PushToast(Translation),
PlaySound(SoundType),
}
impl<T: 'static> Frontend<T> {
@@ -153,6 +166,7 @@ impl<T: 'static> Frontend<T> {
window_audio_settings: WguiWindow::default(),
view_audio_settings: None,
executor: Rc::new(smol::LocalExecutor::new()),
sounds_to_play: Vec::new(),
};
// init some things first
@@ -164,20 +178,25 @@ impl<T: 'static> Frontend<T> {
Ok(frontend)
}
pub fn play_startup_sound(&mut self, audio_system: &mut audio::AudioSystem) -> anyhow::Result<()> {
// play startup sound
let mut assets = self.globals.assets_builtin();
fn queue_play_sound(&mut self, sound_type: SoundType) {
self.sounds_to_play.push(sound_type);
}
let sample_startup = audio::AudioSample::from_mp3(&assets.load_from_path("sound/startup.mp3")?)?;
audio_system.play_sample(&sample_startup);
fn play_sound(&mut self, audio_system: &mut audio::AudioSystem, sound_type: SoundType) -> anyhow::Result<()> {
let mut assets = self.globals.assets_builtin();
let sample = audio::AudioSample::from_mp3(&assets.load_from_path(match sound_type {
SoundType::Startup => "sound/startup.mp3",
SoundType::Launch => "sound/app_start.mp3",
})?)?;
audio_system.play_sample(&sample);
Ok(())
}
pub fn update(&mut self, params: FrontendUpdateParams<T>) -> anyhow::Result<LayoutUpdateResult> {
pub fn update(&mut self, mut params: FrontendUpdateParams<T>) -> anyhow::Result<FrontendUpdateResult> {
let mut tasks = self.tasks.drain();
while let Some(task) = tasks.pop_front() {
self.process_task(params.data, task)?;
self.process_task(&mut params, task)?;
}
if let Some(mut tab) = self.current_tab.take() {
@@ -190,13 +209,27 @@ impl<T: 'static> Frontend<T> {
while self.executor.try_tick() {}
let res = self.tick(params)?;
self.ticks += 1;
Ok(res)
}
fn tick(&mut self, params: FrontendUpdateParams<T>) -> anyhow::Result<LayoutUpdateResult> {
pub fn process_update(
&mut self,
res: FrontendUpdateResult,
audio_system: &mut audio::AudioSystem,
audio_sample_player: &mut audio::SamplePlayer,
) -> anyhow::Result<()> {
for sound_type in res.sounds_to_play {
self.play_sound(audio_system, sound_type)?;
}
audio_sample_player.play_wgui_samples(audio_system, res.layout_result.sounds_to_play);
Ok(())
}
fn tick(&mut self, params: FrontendUpdateParams<T>) -> anyhow::Result<FrontendUpdateResult> {
// fixme: timer events instead of this thing
if self.ticks.is_multiple_of(1000) {
self.update_time()?;
@@ -209,9 +242,14 @@ impl<T: 'static> Frontend<T> {
}
}
self.layout.update(&mut LayoutUpdateParams {
let layout_result = self.layout.update(&mut LayoutUpdateParams {
size: Vec2::new(params.width, params.height),
timestep_alpha: params.timestep_alpha,
})?;
Ok(FrontendUpdateResult {
layout_result,
sounds_to_play: std::mem::take(&mut self.sounds_to_play),
})
}
@@ -283,17 +321,18 @@ impl<T: 'static> Frontend<T> {
Ok(())
}
fn process_task(&mut self, data: &mut T, task: FrontendTask) -> anyhow::Result<()> {
fn process_task(&mut self, params: &mut FrontendUpdateParams<T>, task: FrontendTask) -> anyhow::Result<()> {
match task {
FrontendTask::SetTab(tab_type) => self.set_tab(data, tab_type)?,
FrontendTask::SetTab(tab_type) => self.set_tab(params.data, tab_type)?,
FrontendTask::RefreshClock => self.update_time()?,
FrontendTask::RefreshBackground => self.update_background()?,
FrontendTask::MountPopup(params) => self.mount_popup(params)?,
FrontendTask::RefreshPopupManager => self.refresh_popup_manager()?,
FrontendTask::ShowAudioSettings => self.action_show_audio_settings()?,
FrontendTask::UpdateAudioSettingsView => self.action_update_audio_settings()?,
FrontendTask::RecenterPlayspace => self.action_recenter_playspace(data)?,
FrontendTask::RecenterPlayspace => self.action_recenter_playspace(params.data)?,
FrontendTask::PushToast(content) => self.toast_manager.push(content),
FrontendTask::PlaySound(sound_type) => self.queue_play_sound(sound_type),
};
Ok(())
}

View File

@@ -15,7 +15,7 @@ use wgui::{
use wlx_common::{dash_interface::BoxDashInterface, desktop_finder::DesktopEntry};
use crate::{
frontend::{FrontendTask, FrontendTasks},
frontend::{FrontendTask, FrontendTasks, SoundType},
settings::SettingsIO,
};
@@ -335,6 +335,8 @@ impl View {
"APPLICATION_STARTED",
)));
params.frontend_tasks.push(FrontendTask::PlaySound(SoundType::Launch));
(*params.on_launched)();
// we're done!

View File

@@ -1,7 +1,7 @@
use std::rc::Rc;
use crate::{
frontend::{FrontendTask, FrontendTasks},
frontend::{FrontendTask, FrontendTasks, SoundType},
util::{
cached_fetcher::{self, CoverArt},
steam_utils::{self, AppID, AppManifest},
@@ -178,6 +178,7 @@ impl View {
.push(FrontendTask::PushToast(Translation::from_translation_key(
"GAME_LAUNCHED",
)));
self.frontend_tasks.push(FrontendTask::PlaySound(SoundType::Launch));
}
Err(e) => {
self

View File

@@ -0,0 +1 @@
../../../wlx-overlay-s/src/assets/sound/wgui_checkbox_check.mp3

View File

@@ -0,0 +1 @@
../../../wlx-overlay-s/src/assets/sound/wgui_checkbox_uncheck.mp3

View File

@@ -70,14 +70,16 @@ impl TestbedDashboard {
}
impl Testbed for TestbedDashboard {
fn update(&mut self, mut params: TestbedUpdateParams) -> anyhow::Result<()> {
fn update(&mut self, params: TestbedUpdateParams) -> anyhow::Result<()> {
let res = self.frontend.update(FrontendUpdateParams {
data: &mut (), /* nothing */
width: params.width,
height: params.height,
timestep_alpha: params.timestep_alpha,
})?;
params.process_layout_result(res);
self
.frontend
.process_update(res, params.audio_system, params.audio_sample_player)?;
Ok(())
}

View File

@@ -15,6 +15,7 @@ use crate::{
i18n::Translation,
layout::{self, WidgetID, WidgetPair},
renderer_vk::text::{FontWeight, TextStyle},
sound::WguiSoundType,
widget::{
ConstructEssentials, EventResult,
label::{WidgetLabel, WidgetLabelParams},
@@ -249,16 +250,21 @@ fn register_event_mouse_release(
state.down = false;
if let Some(self_ref) = state.self_ref.upgrade()
&& let Some(radio) = data.radio_group.as_ref().and_then(|r| r.upgrade())
&& let Some(radio) = data.radio_group.as_ref().and_then(Weak::upgrade)
{
radio.set_selected_internal(common, &self_ref)?;
state.checked = true; // can't uncheck radiobox by clicking the checked box again
common.alterables.play_sound(WguiSoundType::CheckboxCheck);
} else {
state.checked = !state.checked;
common.alterables.play_sound(if state.checked {
WguiSoundType::CheckboxCheck
} else {
WguiSoundType::CheckboxUncheck
});
}
set_box_checked(&common.state.widgets, &data, state.checked);
if state.hovered
&& let Some(on_toggle) = &state.on_toggle
{
@@ -383,7 +389,7 @@ pub fn construct(ess: &mut ConstructEssentials, params: Params) -> anyhow::Resul
id_inner_box: inner_box.id,
id_label: label.id,
value: params.value,
radio_group: params.radio_group.as_ref().map(|x| Rc::downgrade(x)),
radio_group: params.radio_group.as_ref().map(Rc::downgrade),
});
let state = Rc::new(RefCell::new(State {

View File

@@ -3,4 +3,6 @@ pub enum WguiSoundType {
ButtonMouseEnter,
ButtonPress,
ButtonRelease,
CheckboxCheck,
CheckboxUncheck,
}

View File

@@ -21,6 +21,8 @@ fn get_sample_name_from_wgui_sound_type(sound: WguiSoundType) -> &'static str {
WguiSoundType::ButtonMouseEnter => "wgui_mouse_enter",
WguiSoundType::ButtonPress => "wgui_button_press",
WguiSoundType::ButtonRelease => "wgui_button_release",
WguiSoundType::CheckboxCheck => "wgui_checkbox_check",
WguiSoundType::CheckboxUncheck => "wgui_checkbox_uncheck",
}
}
@@ -62,6 +64,8 @@ impl SamplePlayer {
load(WguiSoundType::ButtonPress)?;
load(WguiSoundType::ButtonRelease)?;
load(WguiSoundType::ButtonMouseEnter)?;
load(WguiSoundType::CheckboxCheck)?;
load(WguiSoundType::CheckboxUncheck)?;
Ok(())
}

Binary file not shown.

View File

@@ -1,5 +1,5 @@
use dash_frontend::{
frontend::{self, FrontendUpdateParams},
frontend::{self, FrontendTask, FrontendUpdateParams},
settings::{self, SettingsIO},
};
use glam::{Affine2, Affine3A, Vec2, vec2, vec3};
@@ -106,12 +106,14 @@ impl DashFrontend {
let settings = SimpleSettingsIO::new();
let interface = DashInterfaceLive::new();
let mut frontend = frontend::Frontend::new(frontend::InitParams {
let frontend = frontend::Frontend::new(frontend::InitParams {
settings: Box::new(settings),
interface: Box::new(interface),
})?;
frontend.play_startup_sound(&mut app.audio_system)?;
frontend
.tasks
.push(FrontendTask::PlaySound(frontend::SoundType::Startup));
let context = WguiContext::new(&mut app.wgui_shared, 1.0)?;
Ok(Self {
@@ -131,7 +133,8 @@ impl DashFrontend {
height: DASH_RES_VEC2.y / GUI_SCALE,
timestep_alpha,
})?;
app_misc::process_layout_result(app, res);
self.inner
.process_update(res, &mut app.audio_system, &mut app.audio_sample_player)?;
Ok(())
}