notification sounds
This commit is contained in:
@@ -13,12 +13,12 @@ use crate::{
|
||||
config,
|
||||
gui::{color_parse, CanvasBuilder, Control},
|
||||
hid::{KeyModifier, VirtualKey, ALT, CTRL, KEYS_TO_MODS, META, SHIFT, SUPER},
|
||||
state::{AppSession, AppState},
|
||||
state::AppState,
|
||||
};
|
||||
use glam::{vec2, vec3a, Affine2, Vec4};
|
||||
use once_cell::sync::Lazy;
|
||||
use regex::Regex;
|
||||
use rodio::{Decoder, OutputStream, OutputStreamHandle, Source};
|
||||
use rodio::{Decoder, Source};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
const PIXELS_PER_UNIT: f32 = 80.;
|
||||
@@ -39,9 +39,6 @@ where
|
||||
let data = KeyboardData {
|
||||
modifiers: 0,
|
||||
processes: vec![],
|
||||
audio_stream: None,
|
||||
first_try: true,
|
||||
audio_handle: None,
|
||||
};
|
||||
|
||||
let mut canvas = CanvasBuilder::new(
|
||||
@@ -142,7 +139,7 @@ fn key_press(
|
||||
) {
|
||||
match control.state.as_mut() {
|
||||
Some(KeyButtonData::Key { vk, pressed }) => {
|
||||
data.key_click(&app.session);
|
||||
data.key_click(app);
|
||||
|
||||
if let PointerMode::Right = mode {
|
||||
data.modifiers |= SHIFT;
|
||||
@@ -155,11 +152,11 @@ fn key_press(
|
||||
Some(KeyButtonData::Modifier { modifier, sticky }) => {
|
||||
*sticky = data.modifiers & *modifier == 0;
|
||||
data.modifiers |= *modifier;
|
||||
data.key_click(&app.session);
|
||||
data.key_click(app);
|
||||
app.hid_provider.set_modifiers(data.modifiers);
|
||||
}
|
||||
Some(KeyButtonData::Macro { verbs }) => {
|
||||
data.key_click(&app.session);
|
||||
data.key_click(app);
|
||||
for (vk, press) in verbs {
|
||||
app.hid_provider.send_key(*vk as _, *press);
|
||||
}
|
||||
@@ -169,7 +166,7 @@ fn key_press(
|
||||
data.processes
|
||||
.retain_mut(|child| !matches!(child.try_wait(), Ok(Some(_))));
|
||||
|
||||
data.key_click(&app.session);
|
||||
data.key_click(app);
|
||||
if let Ok(child) = Command::new(program).args(args).spawn() {
|
||||
data.processes.push(child);
|
||||
}
|
||||
@@ -228,28 +225,16 @@ fn test_highlight(
|
||||
struct KeyboardData {
|
||||
modifiers: KeyModifier,
|
||||
processes: Vec<Child>,
|
||||
audio_stream: Option<OutputStream>,
|
||||
audio_handle: Option<OutputStreamHandle>,
|
||||
first_try: bool,
|
||||
}
|
||||
|
||||
impl KeyboardData {
|
||||
fn key_click(&mut self, session: &AppSession) {
|
||||
if !session.config.keyboard_sound_enabled {
|
||||
fn key_click(&mut self, app: &mut AppState) {
|
||||
if !app.session.config.keyboard_sound_enabled {
|
||||
return;
|
||||
}
|
||||
|
||||
if self.audio_stream.is_none() && self.first_try {
|
||||
self.first_try = false;
|
||||
if let Ok((stream, handle)) = OutputStream::try_default() {
|
||||
self.audio_stream = Some(stream);
|
||||
self.audio_handle = Some(handle);
|
||||
} else {
|
||||
log::error!("Failed to open audio stream");
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(handle) = &self.audio_handle {
|
||||
if let Some(handle) = app.audio.get_handle() {
|
||||
// https://freesound.org/people/UberBosser/sounds/421581/
|
||||
let wav = include_bytes!("../res/421581.wav");
|
||||
let cursor = Cursor::new(wav);
|
||||
let source = Decoder::new_wav(cursor).unwrap();
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
use std::{
|
||||
io::Cursor,
|
||||
ops::Add,
|
||||
sync::{atomic::AtomicUsize, Arc},
|
||||
};
|
||||
|
||||
use rodio::{Decoder, Source};
|
||||
|
||||
use glam::vec3a;
|
||||
|
||||
use crate::{
|
||||
@@ -24,8 +27,8 @@ pub struct Toast {
|
||||
pub title: Arc<str>,
|
||||
pub body: Arc<str>,
|
||||
pub opacity: f32,
|
||||
pub volume: f32,
|
||||
pub timeout: f32,
|
||||
pub sound: bool,
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
@@ -36,7 +39,7 @@ impl Toast {
|
||||
body,
|
||||
opacity: 1.0,
|
||||
timeout: 3.0,
|
||||
volume: 0.0,
|
||||
sound: false,
|
||||
}
|
||||
}
|
||||
pub fn with_timeout(mut self, timeout: f32) -> Self {
|
||||
@@ -47,8 +50,8 @@ impl Toast {
|
||||
self.opacity = opacity;
|
||||
self
|
||||
}
|
||||
pub fn with_volume(mut self, volume: f32) -> Self {
|
||||
self.volume = volume;
|
||||
pub fn with_sound(mut self, sound: bool) -> Self {
|
||||
self.sound = sound;
|
||||
self
|
||||
}
|
||||
pub fn submit(self, app: &mut AppState) {
|
||||
@@ -59,6 +62,8 @@ impl Toast {
|
||||
let destroy_at =
|
||||
std::time::Instant::now().add(std::time::Duration::from_secs_f32(self.timeout));
|
||||
|
||||
let has_sound = self.sound;
|
||||
|
||||
app.tasks.enqueue(TaskType::CreateOverlay(
|
||||
selector.clone(),
|
||||
Box::new(move |app| new_toast(self, name, app)),
|
||||
@@ -66,6 +71,15 @@ impl Toast {
|
||||
|
||||
app.tasks
|
||||
.enqueue_at(TaskType::DropOverlay(selector), destroy_at);
|
||||
|
||||
if has_sound {
|
||||
if let Some(handle) = app.audio.get_handle() {
|
||||
let wav = include_bytes!("../res/557297.wav");
|
||||
let cursor = Cursor::new(wav);
|
||||
let source = Decoder::new_wav(cursor).unwrap();
|
||||
let _ = handle.play_raw(source.convert_samples());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,9 +105,11 @@ fn new_toast(
|
||||
.ok()?;
|
||||
(w0.max(w1), h1 + 50.)
|
||||
} else {
|
||||
app.fc
|
||||
let (w, h) = app
|
||||
.fc
|
||||
.get_text_size(&title, FONT_SIZE, app.graphics.clone())
|
||||
.ok()?
|
||||
.ok()?;
|
||||
(w, h + 20.)
|
||||
};
|
||||
|
||||
let og_width = size.0;
|
||||
@@ -123,7 +139,7 @@ fn new_toast(
|
||||
canvas.label_centered(PADDING.0, 16., og_width, FONT_SIZE as f32 + 2., title);
|
||||
} else {
|
||||
log::info!("Toast: {}", title);
|
||||
canvas.label(0., 0., size.0, size.1, title);
|
||||
canvas.label_centered(PADDING.0, 0., og_width, size.1, title);
|
||||
}
|
||||
|
||||
let state = OverlayState {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use std::{
|
||||
f32::consts::PI,
|
||||
io::Read,
|
||||
io::{Cursor, Read},
|
||||
process::{self, Stdio},
|
||||
sync::Arc,
|
||||
time::Instant,
|
||||
@@ -9,6 +9,7 @@ use std::{
|
||||
use chrono::Local;
|
||||
use chrono_tz::Tz;
|
||||
use glam::{Quat, Vec3, Vec3A};
|
||||
use rodio::{Decoder, Source};
|
||||
use serde::Deserialize;
|
||||
|
||||
use crate::{
|
||||
@@ -395,6 +396,15 @@ fn btn_mirror_dn(
|
||||
}
|
||||
}
|
||||
|
||||
fn audio_thump(app: &mut AppState) {
|
||||
if let Some(handle) = app.audio.get_handle() {
|
||||
let wav = include_bytes!("../res/380885.wav");
|
||||
let cursor = Cursor::new(wav);
|
||||
let source = Decoder::new_wav(cursor).unwrap();
|
||||
let _ = handle.play_raw(source.convert_samples());
|
||||
}
|
||||
}
|
||||
|
||||
fn btn_func_dn(
|
||||
control: &mut Control<(), ElemState>,
|
||||
_: &mut (),
|
||||
@@ -434,6 +444,7 @@ fn btn_func_dn(
|
||||
.submit(app);
|
||||
}),
|
||||
));
|
||||
audio_thump(app);
|
||||
}
|
||||
ButtonFunc::SwitchWatchHand => {
|
||||
app.tasks.enqueue(TaskType::Overlay(
|
||||
@@ -456,6 +467,7 @@ fn btn_func_dn(
|
||||
.submit(app);
|
||||
}),
|
||||
));
|
||||
audio_thump(app);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -736,6 +748,7 @@ fn overlay_button_up(control: &mut Control<(), ElemState>, _: &mut (), app: &mut
|
||||
}
|
||||
}),
|
||||
));
|
||||
audio_thump(app);
|
||||
}
|
||||
PointerMode::Middle => {
|
||||
app.tasks.enqueue(TaskType::Overlay(
|
||||
@@ -751,6 +764,7 @@ fn overlay_button_up(control: &mut Control<(), ElemState>, _: &mut (), app: &mut
|
||||
}
|
||||
}),
|
||||
));
|
||||
audio_thump(app);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user