feat: toast topics
This commit is contained in:
1
Cargo.lock
generated
1
Cargo.lock
generated
@@ -1537,6 +1537,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "dba885f996064df334b1639785897d1c58c0646750101b839b8359664cb26c0e"
|
checksum = "dba885f996064df334b1639785897d1c58c0646750101b839b8359664cb26c0e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"fixedbitset",
|
"fixedbitset",
|
||||||
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ fontconfig-rs = "0.1.1"
|
|||||||
freetype-rs = "0.32.0"
|
freetype-rs = "0.32.0"
|
||||||
futures = "0.3.29"
|
futures = "0.3.29"
|
||||||
glam = { version = "0.24.1", features = ["approx"] }
|
glam = { version = "0.24.1", features = ["approx"] }
|
||||||
idmap = "0.2.21"
|
idmap = { version = "0.2.21", features = ["serde"] }
|
||||||
idmap-derive = "0.1.2"
|
idmap-derive = "0.1.2"
|
||||||
input-linux = "0.6.0"
|
input-linux = "0.6.0"
|
||||||
json = { version = "0.12.4", optional = true }
|
json = { version = "0.12.4", optional = true }
|
||||||
|
|||||||
@@ -9,7 +9,12 @@ use std::{
|
|||||||
time::Duration,
|
time::Duration,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{config::def_true, config_io, overlays::toast::Toast, state::AppState};
|
use crate::{
|
||||||
|
config::def_true,
|
||||||
|
config_io,
|
||||||
|
overlays::toast::{Toast, ToastTopic},
|
||||||
|
state::AppState,
|
||||||
|
};
|
||||||
|
|
||||||
pub struct NotificationManager {
|
pub struct NotificationManager {
|
||||||
rx_toast: mpsc::Receiver<Toast>,
|
rx_toast: mpsc::Receiver<Toast>,
|
||||||
@@ -167,7 +172,11 @@ impl NotificationManager {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let toast = Toast::new(msg.title, msg.content.unwrap_or_else(|| "".into()))
|
let toast = Toast::new(
|
||||||
|
ToastTopic::XSNotification,
|
||||||
|
msg.title,
|
||||||
|
msg.content.unwrap_or_else(|| "".into()),
|
||||||
|
)
|
||||||
.with_timeout(msg.timeout.unwrap_or(5.))
|
.with_timeout(msg.timeout.unwrap_or(5.))
|
||||||
.with_sound(msg.volume.unwrap_or(-1.) >= 0.); // XSOverlay still plays at 0,
|
.with_sound(msg.volume.unwrap_or(-1.) >= 0.); // XSOverlay still plays at 0,
|
||||||
|
|
||||||
@@ -204,9 +213,11 @@ fn parse_dbus(msg: &dbus::Message) -> anyhow::Result<Toast> {
|
|||||||
summary
|
summary
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(Toast::new(title.into(), body.into())
|
Ok(
|
||||||
|
Toast::new(ToastTopic::DesktopNotification, title.into(), body.into())
|
||||||
.with_timeout(5.0)
|
.with_timeout(5.0)
|
||||||
.with_opacity(1.0))
|
.with_opacity(1.0),
|
||||||
|
)
|
||||||
// leave the audio part to the desktop env
|
// leave the audio part to the desktop env
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,10 @@ use crate::{
|
|||||||
overlay::OverlayData,
|
overlay::OverlayData,
|
||||||
},
|
},
|
||||||
graphics::WlxGraphics,
|
graphics::WlxGraphics,
|
||||||
overlays::watch::{watch_fade, WATCH_NAME},
|
overlays::{
|
||||||
|
toast::{Toast, ToastTopic},
|
||||||
|
watch::{watch_fade, WATCH_NAME},
|
||||||
|
},
|
||||||
state::AppState,
|
state::AppState,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -178,6 +181,12 @@ pub fn openvr_run(running: Arc<AtomicBool>) -> Result<(), BackendError> {
|
|||||||
let ipd = (ipd * 10000.0).round() * 0.1;
|
let ipd = (ipd * 10000.0).round() * 0.1;
|
||||||
if (ipd - state.input_state.ipd).abs() > 0.05 {
|
if (ipd - state.input_state.ipd).abs() > 0.05 {
|
||||||
log::info!("IPD: {:.1} mm -> {:.1} mm", state.input_state.ipd, ipd);
|
log::info!("IPD: {:.1} mm -> {:.1} mm", state.input_state.ipd, ipd);
|
||||||
|
Toast::new(
|
||||||
|
ToastTopic::IpdChange,
|
||||||
|
"IPD".into(),
|
||||||
|
format!("{:.1} mm", ipd).into(),
|
||||||
|
)
|
||||||
|
.submit(&mut state);
|
||||||
}
|
}
|
||||||
state.input_state.ipd = ipd;
|
state.input_state.ipd = ipd;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,10 @@ use crate::{
|
|||||||
overlay::OverlayData,
|
overlay::OverlayData,
|
||||||
},
|
},
|
||||||
graphics::WlxGraphics,
|
graphics::WlxGraphics,
|
||||||
overlays::watch::{watch_fade, WATCH_NAME},
|
overlays::{
|
||||||
|
toast::{Toast, ToastTopic},
|
||||||
|
watch::{watch_fade, WATCH_NAME},
|
||||||
|
},
|
||||||
state::AppState,
|
state::AppState,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -220,8 +223,18 @@ pub fn openxr_run(running: Arc<AtomicBool>) -> Result<(), BackendError> {
|
|||||||
&xr_state.stage,
|
&xr_state.stage,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
(app_state.input_state.hmd, app_state.input_state.ipd) =
|
let (hmd, ipd) = helpers::hmd_pose_from_views(&views);
|
||||||
helpers::hmd_pose_from_views(&views);
|
app_state.input_state.hmd = hmd;
|
||||||
|
if (app_state.input_state.ipd - ipd).abs() > 0.01 {
|
||||||
|
log::info!("IPD changed: {} -> {}", app_state.input_state.ipd, ipd);
|
||||||
|
app_state.input_state.ipd = ipd;
|
||||||
|
Toast::new(
|
||||||
|
ToastTopic::IpdChange,
|
||||||
|
"IPD".into(),
|
||||||
|
format!("{:.1} mm", ipd).into(),
|
||||||
|
)
|
||||||
|
.submit(&mut app_state);
|
||||||
|
}
|
||||||
|
|
||||||
overlays
|
overlays
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
|
|||||||
@@ -4,8 +4,11 @@ use crate::config_io;
|
|||||||
use crate::config_io::get_conf_d_path;
|
use crate::config_io::get_conf_d_path;
|
||||||
use crate::gui::modular::ModularUiConfig;
|
use crate::gui::modular::ModularUiConfig;
|
||||||
use crate::load_with_fallback;
|
use crate::load_with_fallback;
|
||||||
|
use crate::overlays::toast::DisplayMethod;
|
||||||
|
use crate::overlays::toast::ToastTopic;
|
||||||
use crate::state::LeftRight;
|
use crate::state::LeftRight;
|
||||||
use anyhow::bail;
|
use anyhow::bail;
|
||||||
|
use idmap::IdMap;
|
||||||
use log::error;
|
use log::error;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
@@ -62,6 +65,15 @@ fn def_auto() -> Arc<str> {
|
|||||||
"auto".into()
|
"auto".into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn def_toast_topics() -> IdMap<ToastTopic, DisplayMethod> {
|
||||||
|
let mut map = IdMap::new();
|
||||||
|
map.insert(ToastTopic::System, DisplayMethod::Center);
|
||||||
|
map.insert(ToastTopic::DesktopNotification, DisplayMethod::Center);
|
||||||
|
map.insert(ToastTopic::XSNotification, DisplayMethod::Center);
|
||||||
|
map.insert(ToastTopic::IpdChange, DisplayMethod::Hide);
|
||||||
|
map
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize)]
|
#[derive(Deserialize, Serialize)]
|
||||||
pub struct GeneralConfig {
|
pub struct GeneralConfig {
|
||||||
#[serde(default = "def_watch_pos")]
|
#[serde(default = "def_watch_pos")]
|
||||||
@@ -103,6 +115,9 @@ pub struct GeneralConfig {
|
|||||||
#[serde(default = "def_pw_tokens")]
|
#[serde(default = "def_pw_tokens")]
|
||||||
pub pw_tokens: Vec<(String, String)>,
|
pub pw_tokens: Vec<(String, String)>,
|
||||||
|
|
||||||
|
#[serde(default = "def_toast_topics")]
|
||||||
|
pub toast_topics: IdMap<ToastTopic, DisplayMethod>,
|
||||||
|
|
||||||
#[serde(default = "def_osc_port")]
|
#[serde(default = "def_osc_port")]
|
||||||
pub osc_out_port: u16,
|
pub osc_out_port: u16,
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ use crate::{
|
|||||||
overlay::RelativeTo,
|
overlay::RelativeTo,
|
||||||
},
|
},
|
||||||
overlays::{
|
overlays::{
|
||||||
toast::Toast,
|
toast::{Toast, ToastTopic},
|
||||||
watch::{save_watch, WATCH_NAME},
|
watch::{save_watch, WATCH_NAME},
|
||||||
},
|
},
|
||||||
state::AppState,
|
state::AppState,
|
||||||
@@ -276,7 +276,11 @@ fn handle_action(action: &ButtonAction, press: &mut PressData, app: &mut AppStat
|
|||||||
body,
|
body,
|
||||||
seconds,
|
seconds,
|
||||||
} => {
|
} => {
|
||||||
Toast::new(message.clone(), body.clone().unwrap_or_else(|| "".into()))
|
Toast::new(
|
||||||
|
ToastTopic::System,
|
||||||
|
message.clone(),
|
||||||
|
body.clone().unwrap_or_else(|| "".into()),
|
||||||
|
)
|
||||||
.with_timeout(seconds.unwrap_or(5.))
|
.with_timeout(seconds.unwrap_or(5.))
|
||||||
.submit(app);
|
.submit(app);
|
||||||
}
|
}
|
||||||
@@ -303,6 +307,7 @@ fn run_system(action: &SystemAction, app: &mut AppState) {
|
|||||||
let at = now.add(i * sec);
|
let at = now.add(i * sec);
|
||||||
let display = 5 - i;
|
let display = 5 - i;
|
||||||
Toast::new(
|
Toast::new(
|
||||||
|
ToastTopic::System,
|
||||||
format!("Fixing floor in {}", display).into(),
|
format!("Fixing floor in {}", display).into(),
|
||||||
"Place either controller on the floor.".into(),
|
"Place either controller on the floor.".into(),
|
||||||
)
|
)
|
||||||
@@ -318,6 +323,7 @@ fn run_system(action: &SystemAction, app: &mut AppState) {
|
|||||||
SystemAction::ToggleNotifications => {
|
SystemAction::ToggleNotifications => {
|
||||||
app.session.config.notifications_enabled = !app.session.config.notifications_enabled;
|
app.session.config.notifications_enabled = !app.session.config.notifications_enabled;
|
||||||
Toast::new(
|
Toast::new(
|
||||||
|
ToastTopic::System,
|
||||||
format!(
|
format!(
|
||||||
"Notifications are {}.",
|
"Notifications are {}.",
|
||||||
if app.session.config.notifications_enabled {
|
if app.session.config.notifications_enabled {
|
||||||
@@ -335,6 +341,7 @@ fn run_system(action: &SystemAction, app: &mut AppState) {
|
|||||||
app.session.config.notifications_sound_enabled =
|
app.session.config.notifications_sound_enabled =
|
||||||
!app.session.config.notifications_sound_enabled;
|
!app.session.config.notifications_sound_enabled;
|
||||||
Toast::new(
|
Toast::new(
|
||||||
|
ToastTopic::System,
|
||||||
format!(
|
format!(
|
||||||
"Notification sounds are {}.",
|
"Notification sounds are {}.",
|
||||||
if app.session.config.notifications_sound_enabled {
|
if app.session.config.notifications_sound_enabled {
|
||||||
@@ -383,7 +390,7 @@ fn run_exec(args: &ExecArgs, toast: &Option<Arc<str>>, press: &mut PressData, ap
|
|||||||
Ok(proc) => {
|
Ok(proc) => {
|
||||||
press.child = Some(proc);
|
press.child = Some(proc);
|
||||||
if let Some(toast) = toast.as_ref() {
|
if let Some(toast) = toast.as_ref() {
|
||||||
Toast::new(toast.clone(), "".into()).submit(app);
|
Toast::new(ToastTopic::System, toast.clone(), "".into()).submit(app);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
@@ -403,6 +410,7 @@ fn run_watch(data: &WatchAction, app: &mut AppState) {
|
|||||||
o.want_visible = false;
|
o.want_visible = false;
|
||||||
o.saved_scale = Some(0.0);
|
o.saved_scale = Some(0.0);
|
||||||
Toast::new(
|
Toast::new(
|
||||||
|
ToastTopic::System,
|
||||||
"Watch hidden".into(),
|
"Watch hidden".into(),
|
||||||
"Use show/hide binding to restore.".into(),
|
"Use show/hide binding to restore.".into(),
|
||||||
)
|
)
|
||||||
@@ -411,7 +419,8 @@ fn run_watch(data: &WatchAction, app: &mut AppState) {
|
|||||||
} else {
|
} else {
|
||||||
o.want_visible = true;
|
o.want_visible = true;
|
||||||
o.saved_scale = None;
|
o.saved_scale = None;
|
||||||
Toast::new("Watch restored".into(), "".into()).submit(app);
|
Toast::new(ToastTopic::System, "Watch restored".into(), "".into())
|
||||||
|
.submit(app);
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
));
|
));
|
||||||
@@ -434,7 +443,11 @@ fn run_watch(data: &WatchAction, app: &mut AppState) {
|
|||||||
o.spawn_point = Vec3A::from_slice(&app.session.config.watch_pos);
|
o.spawn_point = Vec3A::from_slice(&app.session.config.watch_pos);
|
||||||
}
|
}
|
||||||
o.dirty = true;
|
o.dirty = true;
|
||||||
Toast::new("Watch switched".into(), "Check your other hand".into())
|
Toast::new(
|
||||||
|
ToastTopic::System,
|
||||||
|
"Watch switched".into(),
|
||||||
|
"Check your other hand".into(),
|
||||||
|
)
|
||||||
.with_timeout(3.)
|
.with_timeout(3.)
|
||||||
.submit(app);
|
.submit(app);
|
||||||
}),
|
}),
|
||||||
@@ -504,7 +517,12 @@ fn run_overlay(overlay: &OverlaySelector, action: &OverlayAction, app: &mut AppS
|
|||||||
overlay.clone(),
|
overlay.clone(),
|
||||||
Box::new(|app, o| {
|
Box::new(|app, o| {
|
||||||
o.reset(app, true);
|
o.reset(app, true);
|
||||||
Toast::new(format!("{} has been reset!", o.name).into(), "".into()).submit(app);
|
Toast::new(
|
||||||
|
ToastTopic::System,
|
||||||
|
format!("{} has been reset!", o.name).into(),
|
||||||
|
"".into(),
|
||||||
|
)
|
||||||
|
.submit(app);
|
||||||
}),
|
}),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@@ -529,12 +547,17 @@ fn run_overlay(overlay: &OverlaySelector, action: &OverlayAction, app: &mut AppS
|
|||||||
o.show_hide = o.recenter;
|
o.show_hide = o.recenter;
|
||||||
if !o.recenter {
|
if !o.recenter {
|
||||||
Toast::new(
|
Toast::new(
|
||||||
|
ToastTopic::System,
|
||||||
format!("{} is now locked in place!", o.name).into(),
|
format!("{} is now locked in place!", o.name).into(),
|
||||||
"".into(),
|
"".into(),
|
||||||
)
|
)
|
||||||
.submit(app);
|
.submit(app);
|
||||||
} else {
|
} else {
|
||||||
Toast::new(format!("{} is now unlocked!", o.name).into(), "".into())
|
Toast::new(
|
||||||
|
ToastTopic::System,
|
||||||
|
format!("{} is now unlocked!", o.name).into(),
|
||||||
|
"".into(),
|
||||||
|
)
|
||||||
.submit(app);
|
.submit(app);
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
@@ -548,12 +571,17 @@ fn run_overlay(overlay: &OverlaySelector, action: &OverlayAction, app: &mut AppS
|
|||||||
o.interactable = !o.interactable;
|
o.interactable = !o.interactable;
|
||||||
if !o.interactable {
|
if !o.interactable {
|
||||||
Toast::new(
|
Toast::new(
|
||||||
|
ToastTopic::System,
|
||||||
format!("{} is now non-interactable!", o.name).into(),
|
format!("{} is now non-interactable!", o.name).into(),
|
||||||
"".into(),
|
"".into(),
|
||||||
)
|
)
|
||||||
.submit(app);
|
.submit(app);
|
||||||
} else {
|
} else {
|
||||||
Toast::new(format!("{} is now interactable!", o.name).into(), "".into())
|
Toast::new(
|
||||||
|
ToastTopic::System,
|
||||||
|
format!("{} is now interactable!", o.name).into(),
|
||||||
|
"".into(),
|
||||||
|
)
|
||||||
.submit(app);
|
.submit(app);
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
@@ -585,7 +613,11 @@ fn run_window(window: &Arc<str>, action: &WindowAction, app: &mut AppState) {
|
|||||||
Box::new({
|
Box::new({
|
||||||
let name = window.clone();
|
let name = window.clone();
|
||||||
move |app| {
|
move |app| {
|
||||||
Toast::new("Check your desktop for popup.".into(), "".into())
|
Toast::new(
|
||||||
|
ToastTopic::System,
|
||||||
|
"Check your desktop for popup.".into(),
|
||||||
|
"".into(),
|
||||||
|
)
|
||||||
.with_sound(true)
|
.with_sound(true)
|
||||||
.submit(app);
|
.submit(app);
|
||||||
crate::overlays::mirror::new_mirror(name.clone(), false, &app.session)
|
crate::overlays::mirror::new_mirror(name.clone(), false, &app.session)
|
||||||
|
|||||||
@@ -4,7 +4,9 @@ use std::{
|
|||||||
time::Instant,
|
time::Instant,
|
||||||
};
|
};
|
||||||
|
|
||||||
use glam::vec3a;
|
use glam::{vec3a, Vec3A};
|
||||||
|
use idmap_derive::IntegerId;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
backend::{
|
backend::{
|
||||||
@@ -12,7 +14,7 @@ use crate::{
|
|||||||
overlay::{OverlayBackend, OverlayState, RelativeTo},
|
overlay::{OverlayBackend, OverlayState, RelativeTo},
|
||||||
},
|
},
|
||||||
gui::{color_parse, CanvasBuilder},
|
gui::{color_parse, CanvasBuilder},
|
||||||
state::AppState,
|
state::{AppState, LeftRight},
|
||||||
};
|
};
|
||||||
|
|
||||||
const FONT_SIZE: isize = 16;
|
const FONT_SIZE: isize = 16;
|
||||||
@@ -22,23 +24,40 @@ const TOAST_AUDIO_WAV: &[u8] = include_bytes!("../res/557297.wav");
|
|||||||
|
|
||||||
static AUTO_INCREMENT: AtomicUsize = AtomicUsize::new(0);
|
static AUTO_INCREMENT: AtomicUsize = AtomicUsize::new(0);
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
|
||||||
|
pub enum DisplayMethod {
|
||||||
|
Hide,
|
||||||
|
Center,
|
||||||
|
Watch,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, IntegerId, Serialize, Deserialize)]
|
||||||
|
pub enum ToastTopic {
|
||||||
|
System,
|
||||||
|
DesktopNotification,
|
||||||
|
XSNotification,
|
||||||
|
IpdChange,
|
||||||
|
}
|
||||||
|
|
||||||
pub struct Toast {
|
pub struct Toast {
|
||||||
pub title: Arc<str>,
|
pub title: Arc<str>,
|
||||||
pub body: Arc<str>,
|
pub body: Arc<str>,
|
||||||
pub opacity: f32,
|
pub opacity: f32,
|
||||||
pub timeout: f32,
|
pub timeout: f32,
|
||||||
pub sound: bool,
|
pub sound: bool,
|
||||||
|
pub topic: ToastTopic,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
impl Toast {
|
impl Toast {
|
||||||
pub fn new(title: Arc<str>, body: Arc<str>) -> Self {
|
pub fn new(topic: ToastTopic, title: Arc<str>, body: Arc<str>) -> Self {
|
||||||
Toast {
|
Toast {
|
||||||
title,
|
title,
|
||||||
body,
|
body,
|
||||||
opacity: 1.0,
|
opacity: 1.0,
|
||||||
timeout: 3.0,
|
timeout: 3.0,
|
||||||
sound: false,
|
sound: false,
|
||||||
|
topic,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn with_timeout(mut self, timeout: f32) -> Self {
|
pub fn with_timeout(mut self, timeout: f32) -> Self {
|
||||||
@@ -87,6 +106,27 @@ fn new_toast(
|
|||||||
name: Arc<str>,
|
name: Arc<str>,
|
||||||
app: &mut AppState,
|
app: &mut AppState,
|
||||||
) -> Option<(OverlayState, Box<dyn OverlayBackend>)> {
|
) -> Option<(OverlayState, Box<dyn OverlayBackend>)> {
|
||||||
|
let current_method = app
|
||||||
|
.session
|
||||||
|
.config
|
||||||
|
.toast_topics
|
||||||
|
.get(&toast.topic)
|
||||||
|
.copied()
|
||||||
|
.unwrap_or(DisplayMethod::Hide);
|
||||||
|
|
||||||
|
let (spawn_point, relative_to) = match current_method {
|
||||||
|
DisplayMethod::Hide => return None,
|
||||||
|
DisplayMethod::Center => (vec3a(0., -2.0, -0.5), RelativeTo::Head),
|
||||||
|
DisplayMethod::Watch => {
|
||||||
|
let relative_to = match app.session.config.watch_hand {
|
||||||
|
LeftRight::Left => RelativeTo::Hand(0),
|
||||||
|
LeftRight::Right => RelativeTo::Hand(1),
|
||||||
|
};
|
||||||
|
let watch_pos = Vec3A::from_slice(&app.session.config.watch_pos);
|
||||||
|
(watch_pos + Vec3A::Y * 0.05, relative_to)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let title = if toast.title.len() > 0 {
|
let title = if toast.title.len() > 0 {
|
||||||
toast.title
|
toast.title
|
||||||
} else {
|
} else {
|
||||||
@@ -143,8 +183,8 @@ fn new_toast(
|
|||||||
name,
|
name,
|
||||||
want_visible: true,
|
want_visible: true,
|
||||||
spawn_scale: size.0 * PIXELS_TO_METERS,
|
spawn_scale: size.0 * PIXELS_TO_METERS,
|
||||||
spawn_point: vec3a(0., -0.2, -0.5),
|
spawn_point,
|
||||||
relative_to: RelativeTo::Head,
|
relative_to,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
let backend = Box::new(canvas.build());
|
let backend = Box::new(canvas.build());
|
||||||
|
|||||||
Reference in New Issue
Block a user