context menus
This commit is contained in:
parent
5e06a3c08e
commit
833f5b96c9
|
@ -1,5 +1,6 @@
|
|||
use std::sync::Arc;
|
||||
use std::sync::Mutex;
|
||||
use std::time::Duration;
|
||||
|
||||
use anyhow::anyhow;
|
||||
use anyhow::Result;
|
||||
|
@ -10,7 +11,7 @@ use cpal::InputCallbackInfo;
|
|||
// use cpal::OutputCallbackInfo;
|
||||
use tauri::Window;
|
||||
|
||||
pub async fn monitor(window: Window, threshold: Arc<Mutex<f32>>) {
|
||||
pub async fn monitor(window: Window, threshold: Arc<Mutex<f32>>, level: Arc<Mutex<f32>>) {
|
||||
let device = initialize().expect("Unable to init audio");
|
||||
println!("Using device {}", device.name().unwrap());
|
||||
let config = device.default_input_config().unwrap();
|
||||
|
@ -23,6 +24,13 @@ pub async fn monitor(window: Window, threshold: Arc<Mutex<f32>>) {
|
|||
} else {
|
||||
window.emit("mouth-close", "").unwrap();
|
||||
}
|
||||
|
||||
*level.lock().unwrap() = data
|
||||
.iter()
|
||||
.map(|e| e.abs())
|
||||
.max_by(|a, b| a.total_cmp(&b))
|
||||
.unwrap()
|
||||
.clone();
|
||||
},
|
||||
move |err| {
|
||||
println!("Audio error: {:?}", err);
|
||||
|
@ -31,8 +39,10 @@ pub async fn monitor(window: Window, threshold: Arc<Mutex<f32>>) {
|
|||
.unwrap();
|
||||
|
||||
println!("Start stream");
|
||||
stream.play().expect("Error creating output stream");
|
||||
loop {} // the stream will close if it goes out of scope, so just dwell here
|
||||
stream.play().expect("Error creating input stream");
|
||||
|
||||
// The stream will end if it goes out of scope, so just dwell here
|
||||
loop {}
|
||||
}
|
||||
|
||||
fn initialize() -> Result<Device> {
|
||||
|
|
|
@ -18,17 +18,20 @@ mod fs;
|
|||
const MIC_THRESHOLD: f32 = 0.5f32;
|
||||
|
||||
struct MicThreshold(Arc<Mutex<f32>>);
|
||||
struct AudioLevel(Arc<Mutex<f32>>);
|
||||
|
||||
fn main() {
|
||||
env_logger::init();
|
||||
let threshold = Arc::new(Mutex::new(MIC_THRESHOLD));
|
||||
let level = Arc::new(Mutex::new(0.));
|
||||
|
||||
tauri::Builder::default()
|
||||
.manage(MicThreshold(threshold.clone()))
|
||||
.manage(AudioLevel(level.clone()))
|
||||
.setup(|app| {
|
||||
let window = app.get_window("main").unwrap();
|
||||
tauri::async_runtime::spawn(async move {
|
||||
monitor(window, threshold).await;
|
||||
monitor(window, threshold, level).await;
|
||||
});
|
||||
|
||||
let window = app.get_window("main").unwrap();
|
||||
|
@ -49,6 +52,7 @@ fn main() {
|
|||
.invoke_handler(tauri::generate_handler![
|
||||
set_mic_threshold,
|
||||
get_mic_threshold,
|
||||
get_audio_level,
|
||||
fs::open_image,
|
||||
])
|
||||
.run(tauri::generate_context!())
|
||||
|
@ -64,3 +68,8 @@ fn set_mic_threshold(threshold: f32, current: State<'_, MicThreshold>) {
|
|||
fn get_mic_threshold(current: State<'_, MicThreshold>) -> f32 {
|
||||
*current.0.lock().unwrap()
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
fn get_audio_level(level: State<'_, AudioLevel>) -> f32 {
|
||||
*level.0.lock().unwrap()
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
<script lang="ts">
|
||||
import { frames } from "../store";
|
||||
import { invoke } from "@tauri-apps/api";
|
||||
import { fade } from "svelte/transition";
|
||||
import Context from "../components/context.svelte";
|
||||
export let index: number;
|
||||
|
||||
let menuTimeout: NodeJS.Timeout | null = null;
|
||||
|
@ -21,22 +23,30 @@
|
|||
//TODO: load frame from ray
|
||||
</script>
|
||||
|
||||
<div
|
||||
class="preview"
|
||||
on:click={openImage}
|
||||
on:contextmenu={openImage}
|
||||
on:mouseenter={() =>
|
||||
(menuTimeout = setTimeout(() => (showMenu = true), 1000))}
|
||||
on:mouseleave={() => {
|
||||
if (menuTimeout) {
|
||||
clearTimeout(menuTimeout);
|
||||
}
|
||||
showMenu = false;
|
||||
}}
|
||||
>
|
||||
<p>{showMenu}</p>
|
||||
{#if src}
|
||||
<img {src} alt="Frame {{ index }}" />
|
||||
<div class="box">
|
||||
<div
|
||||
class="preview"
|
||||
on:click={openImage}
|
||||
on:contextmenu={openImage}
|
||||
on:mouseenter={() =>
|
||||
(menuTimeout = setTimeout(() => (showMenu = true), 200))}
|
||||
on:mouseleave={() => {
|
||||
if (menuTimeout) {
|
||||
clearTimeout(menuTimeout);
|
||||
}
|
||||
showMenu = false;
|
||||
}}
|
||||
>
|
||||
{#if src}
|
||||
<img {src} alt="Frame {{ index }}" />
|
||||
{/if}
|
||||
</div>
|
||||
{#if showMenu}
|
||||
<div transition:fade={{ duration: 50 }} class="context">
|
||||
<Context>
|
||||
<p>Context Menu</p>
|
||||
</Context>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
|
@ -55,6 +65,14 @@
|
|||
height: 20vh;
|
||||
}
|
||||
|
||||
.box {
|
||||
gap: 10px;
|
||||
display: flex;
|
||||
.context {
|
||||
align-self: center;
|
||||
}
|
||||
}
|
||||
|
||||
img {
|
||||
width: 75%;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
<script lang="ts">
|
||||
</script>
|
||||
|
||||
<div class="context">
|
||||
<slot />
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.context {
|
||||
color: white;
|
||||
background-color: rgba(75, 75, 75, 10);
|
||||
padding: 1vh;
|
||||
border-radius: 10px;
|
||||
align-self: center;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1 @@
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
let transparent = false;
|
||||
let threshold = 0.0;
|
||||
let level = 0.0;
|
||||
|
||||
onMount(async () => {
|
||||
await appWindow.setMinSize(new PhysicalSize(720, 600));
|
||||
|
@ -18,15 +19,15 @@
|
|||
setInterval(async () => {
|
||||
threshold = await invoke("get_mic_threshold");
|
||||
}, 500);
|
||||
// setInterval(async () => {
|
||||
// await invoke("set_mic_threshold", {
|
||||
// threshold: (threshold + 0.2) % 1.0,
|
||||
// });
|
||||
// }, 1000);
|
||||
|
||||
setInterval(async () => {
|
||||
level = await invoke("get_audio_level");
|
||||
}, 50);
|
||||
});
|
||||
</script>
|
||||
|
||||
<div class="container" class:transparent>
|
||||
<Tuber />
|
||||
{#if !transparent}
|
||||
<div
|
||||
transition:fly={{ duration: 200, x: -200, opacity: 100 }}
|
||||
|
@ -39,10 +40,9 @@
|
|||
|
||||
<div transition:fly={{ duration: 200, x: 200, opacity: 100 }} class="audio">
|
||||
<p>{threshold.toPrecision(2).toString()}</p>
|
||||
<p>{(level * 100).toPrecision(3).toString()}</p>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<Tuber />
|
||||
</div>
|
||||
|
||||
<svelte:body on:contextmenu|preventDefault />
|
||||
|
@ -62,6 +62,7 @@
|
|||
.audio {
|
||||
position: absolute;
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
bottom: 5vh;
|
||||
top: 5vh;
|
||||
right: 30px;
|
||||
|
|
Loading…
Reference in New Issue