fmt
This commit is contained in:
@@ -1,8 +1,7 @@
|
|||||||
use bytes::BufMut;
|
use bytes::BufMut;
|
||||||
use interprocess::local_socket::{
|
use interprocess::local_socket::{
|
||||||
self,
|
self, GenericNamespaced,
|
||||||
tokio::{prelude::*, Stream},
|
tokio::{Stream, prelude::*},
|
||||||
GenericNamespaced,
|
|
||||||
};
|
};
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
|
|||||||
@@ -64,10 +64,7 @@ macro_rules! gen_id {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn iter_mut(
|
pub fn iter_mut(&mut self, callback: &mut dyn FnMut($handle_name, &mut $instance_name)) {
|
||||||
&mut self,
|
|
||||||
callback: &mut dyn FnMut($handle_name, &mut $instance_name),
|
|
||||||
) {
|
|
||||||
for (idx, opt_cell) in self.vec.iter_mut().enumerate() {
|
for (idx, opt_cell) in self.vec.iter_mut().enumerate() {
|
||||||
if let Some(cell) = opt_cell {
|
if let Some(cell) = opt_cell {
|
||||||
let handle = $container_name::get_handle(&cell, idx);
|
let handle = $container_name::get_handle(&cell, idx);
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
use std::{collections::HashMap};
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use wayvr_ipc::{client::{WayVRClient, WayVRClientMutex}, ipc, packet_client, packet_server};
|
use wayvr_ipc::{
|
||||||
|
client::{WayVRClient, WayVRClientMutex},
|
||||||
|
ipc, packet_client, packet_server,
|
||||||
|
};
|
||||||
|
|
||||||
pub struct WayVRClientState {
|
pub struct WayVRClientState {
|
||||||
pub wayvr_client: WayVRClientMutex,
|
pub wayvr_client: WayVRClientMutex,
|
||||||
@@ -19,7 +22,6 @@ fn handle_empty_result(result: anyhow::Result<()>) {
|
|||||||
fn handle_result<T: Serialize>(pretty_print: bool, result: anyhow::Result<T>) {
|
fn handle_result<T: Serialize>(pretty_print: bool, result: anyhow::Result<T>) {
|
||||||
match result {
|
match result {
|
||||||
Ok(t) => {
|
Ok(t) => {
|
||||||
|
|
||||||
let maybe_json = if pretty_print {
|
let maybe_json = if pretty_print {
|
||||||
serde_json::to_string_pretty(&t)
|
serde_json::to_string_pretty(&t)
|
||||||
} else {
|
} else {
|
||||||
@@ -28,10 +30,10 @@ fn handle_result<T: Serialize>(pretty_print: bool, result: anyhow::Result<T>) {
|
|||||||
|
|
||||||
match maybe_json {
|
match maybe_json {
|
||||||
Ok(json_string) => println!("{}", json_string),
|
Ok(json_string) => println!("{}", json_string),
|
||||||
Err(e) => log::error!("Failed to serialize JSON: {e:?}")
|
Err(e) => log::error!("Failed to serialize JSON: {e:?}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(e) => log::error!("{e:?}")
|
Err(e) => log::error!("{e:?}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -43,7 +45,8 @@ pub async fn wvr_display_create(
|
|||||||
scale: Option<f32>,
|
scale: Option<f32>,
|
||||||
attach_to: packet_client::AttachTo,
|
attach_to: packet_client::AttachTo,
|
||||||
) {
|
) {
|
||||||
handle_result(state.pretty_print,
|
handle_result(
|
||||||
|
state.pretty_print,
|
||||||
WayVRClient::fn_wvr_display_create(
|
WayVRClient::fn_wvr_display_create(
|
||||||
state.wayvr_client.clone(),
|
state.wayvr_client.clone(),
|
||||||
state.serial_generator.increment_get(),
|
state.serial_generator.increment_get(),
|
||||||
@@ -55,47 +58,52 @@ pub async fn wvr_display_create(
|
|||||||
attach_to,
|
attach_to,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.await.context("failed to create display")
|
.await
|
||||||
|
.context("failed to create display"),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn wvr_display_list(
|
pub async fn wvr_display_list(state: &mut WayVRClientState) {
|
||||||
state: &mut WayVRClientState,
|
handle_result(
|
||||||
) {
|
state.pretty_print,
|
||||||
handle_result(state.pretty_print,
|
|
||||||
WayVRClient::fn_wvr_display_list(
|
WayVRClient::fn_wvr_display_list(
|
||||||
state.wayvr_client.clone(),
|
state.wayvr_client.clone(),
|
||||||
state.serial_generator.increment_get(),
|
state.serial_generator.increment_get(),
|
||||||
)
|
)
|
||||||
.await.context("failed to fetch displays")
|
.await
|
||||||
);
|
.context("failed to fetch displays"),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn wvr_display_get(
|
pub async fn wvr_display_get(
|
||||||
state: &mut WayVRClientState,
|
state: &mut WayVRClientState,
|
||||||
handle: packet_server::WvrDisplayHandle,
|
handle: packet_server::WvrDisplayHandle,
|
||||||
) {
|
) {
|
||||||
handle_result(state.pretty_print,
|
handle_result(
|
||||||
|
state.pretty_print,
|
||||||
WayVRClient::fn_wvr_display_get(
|
WayVRClient::fn_wvr_display_get(
|
||||||
state.wayvr_client.clone(),
|
state.wayvr_client.clone(),
|
||||||
state.serial_generator.increment_get(),
|
state.serial_generator.increment_get(),
|
||||||
handle,
|
handle,
|
||||||
)
|
)
|
||||||
.await.context("failed to fetch display")
|
.await
|
||||||
);
|
.context("failed to fetch display"),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn wvr_display_window_list(
|
pub async fn wvr_display_window_list(
|
||||||
state: &mut WayVRClientState,
|
state: &mut WayVRClientState,
|
||||||
handle: packet_server::WvrDisplayHandle,
|
handle: packet_server::WvrDisplayHandle,
|
||||||
) {
|
) {
|
||||||
handle_result(state.pretty_print,
|
handle_result(
|
||||||
|
state.pretty_print,
|
||||||
WayVRClient::fn_wvr_display_window_list(
|
WayVRClient::fn_wvr_display_window_list(
|
||||||
state.wayvr_client.clone(),
|
state.wayvr_client.clone(),
|
||||||
state.serial_generator.increment_get(),
|
state.serial_generator.increment_get(),
|
||||||
handle,
|
handle,
|
||||||
)
|
)
|
||||||
.await.context("failed to list window displays")
|
.await
|
||||||
|
.context("failed to list window displays"),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -103,13 +111,15 @@ pub async fn wvr_display_remove(
|
|||||||
state: &mut WayVRClientState,
|
state: &mut WayVRClientState,
|
||||||
handle: packet_server::WvrDisplayHandle,
|
handle: packet_server::WvrDisplayHandle,
|
||||||
) {
|
) {
|
||||||
handle_result(state.pretty_print,
|
handle_result(
|
||||||
|
state.pretty_print,
|
||||||
WayVRClient::fn_wvr_display_remove(
|
WayVRClient::fn_wvr_display_remove(
|
||||||
state.wayvr_client.clone(),
|
state.wayvr_client.clone(),
|
||||||
state.serial_generator.increment_get(),
|
state.serial_generator.increment_get(),
|
||||||
handle,
|
handle,
|
||||||
)
|
)
|
||||||
.await.context("failed to remove display")
|
.await
|
||||||
|
.context("failed to remove display"),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,7 +129,9 @@ pub async fn wvr_display_set_visible(
|
|||||||
visible: bool,
|
visible: bool,
|
||||||
) {
|
) {
|
||||||
handle_empty_result(
|
handle_empty_result(
|
||||||
WayVRClient::fn_wvr_display_set_visible(state.wayvr_client.clone(), handle, visible).await.context("failed to set display visibility"),
|
WayVRClient::fn_wvr_display_set_visible(state.wayvr_client.clone(), handle, visible)
|
||||||
|
.await
|
||||||
|
.context("failed to set display visibility"),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -129,7 +141,9 @@ pub async fn wvr_window_set_visible(
|
|||||||
visible: bool,
|
visible: bool,
|
||||||
) {
|
) {
|
||||||
handle_empty_result(
|
handle_empty_result(
|
||||||
WayVRClient::fn_wvr_window_set_visible(state.wayvr_client.clone(), handle, visible).await.context("failed to set window visibility"),
|
WayVRClient::fn_wvr_window_set_visible(state.wayvr_client.clone(), handle, visible)
|
||||||
|
.await
|
||||||
|
.context("failed to set window visibility"),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,25 +151,27 @@ pub async fn wvr_process_get(
|
|||||||
state: &mut WayVRClientState,
|
state: &mut WayVRClientState,
|
||||||
handle: packet_server::WvrProcessHandle,
|
handle: packet_server::WvrProcessHandle,
|
||||||
) {
|
) {
|
||||||
handle_result(state.pretty_print,
|
handle_result(
|
||||||
|
state.pretty_print,
|
||||||
WayVRClient::fn_wvr_process_get(
|
WayVRClient::fn_wvr_process_get(
|
||||||
state.wayvr_client.clone(),
|
state.wayvr_client.clone(),
|
||||||
state.serial_generator.increment_get(),
|
state.serial_generator.increment_get(),
|
||||||
handle,
|
handle,
|
||||||
)
|
)
|
||||||
.await.context("failed to get process"),
|
.await
|
||||||
|
.context("failed to get process"),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn wvr_process_list(
|
pub async fn wvr_process_list(state: &mut WayVRClientState) {
|
||||||
state: &mut WayVRClientState,
|
handle_result(
|
||||||
) {
|
state.pretty_print,
|
||||||
handle_result(state.pretty_print,
|
|
||||||
WayVRClient::fn_wvr_process_list(
|
WayVRClient::fn_wvr_process_list(
|
||||||
state.wayvr_client.clone(),
|
state.wayvr_client.clone(),
|
||||||
state.serial_generator.increment_get(),
|
state.serial_generator.increment_get(),
|
||||||
)
|
)
|
||||||
.await.context("failed to list processes"),
|
.await
|
||||||
|
.context("failed to list processes"),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -164,7 +180,9 @@ pub async fn wvr_process_terminate(
|
|||||||
handle: packet_server::WvrProcessHandle,
|
handle: packet_server::WvrProcessHandle,
|
||||||
) {
|
) {
|
||||||
handle_empty_result(
|
handle_empty_result(
|
||||||
WayVRClient::fn_wvr_process_terminate(state.wayvr_client.clone(), handle).await.context("failed to terminate process"),
|
WayVRClient::fn_wvr_process_terminate(state.wayvr_client.clone(), handle)
|
||||||
|
.await
|
||||||
|
.context("failed to terminate process"),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -177,7 +195,8 @@ pub async fn wvr_process_launch(
|
|||||||
args: String,
|
args: String,
|
||||||
userdata: HashMap<String, String>,
|
userdata: HashMap<String, String>,
|
||||||
) {
|
) {
|
||||||
handle_result(state.pretty_print,
|
handle_result(
|
||||||
|
state.pretty_print,
|
||||||
WayVRClient::fn_wvr_process_launch(
|
WayVRClient::fn_wvr_process_launch(
|
||||||
state.wayvr_client.clone(),
|
state.wayvr_client.clone(),
|
||||||
state.serial_generator.increment_get(),
|
state.serial_generator.increment_get(),
|
||||||
@@ -190,7 +209,8 @@ pub async fn wvr_process_launch(
|
|||||||
userdata,
|
userdata,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.await.context("failed to launch process"),
|
.await
|
||||||
|
.context("failed to launch process"),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -209,7 +229,8 @@ pub async fn wlx_haptics(
|
|||||||
frequency,
|
frequency,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.await.context("failed to trigger haptics"),
|
.await
|
||||||
|
.context("failed to trigger haptics"),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -228,19 +249,19 @@ pub async fn wlx_panel_modify(
|
|||||||
command,
|
command,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.await.context("failed to modify panel"),
|
.await
|
||||||
|
.context("failed to modify panel"),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn wlx_input_state(
|
pub async fn wlx_input_state(state: &mut WayVRClientState) {
|
||||||
state: &mut WayVRClientState,
|
handle_result(
|
||||||
) {
|
state.pretty_print,
|
||||||
handle_result(state.pretty_print,
|
|
||||||
WayVRClient::fn_wlx_input_state(
|
WayVRClient::fn_wlx_input_state(
|
||||||
state.wayvr_client.clone(),
|
state.wayvr_client.clone(),
|
||||||
state.serial_generator.increment_get(),
|
state.serial_generator.increment_get(),
|
||||||
)
|
)
|
||||||
.await.context("failed to get input state"),
|
.await
|
||||||
|
.context("failed to get input state"),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,36 +1,47 @@
|
|||||||
use std::{collections::HashMap, process::{self, ExitCode}, time::Duration};
|
use std::{
|
||||||
|
collections::HashMap,
|
||||||
|
process::{self, ExitCode},
|
||||||
|
time::Duration,
|
||||||
|
};
|
||||||
|
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use env_logger::Env;
|
use env_logger::Env;
|
||||||
use wayvr_ipc::{client::WayVRClient, ipc, packet_client, };
|
use wayvr_ipc::{client::WayVRClient, ipc, packet_client};
|
||||||
|
|
||||||
use crate::helper::{wlx_haptics, wlx_input_state, wlx_panel_modify, wvr_display_create, wvr_display_get, wvr_display_list, wvr_display_remove, wvr_display_set_visible, wvr_display_window_list, wvr_process_get, wvr_process_launch, wvr_process_list, wvr_process_terminate, wvr_window_set_visible, WayVRClientState};
|
use crate::helper::{
|
||||||
|
WayVRClientState, wlx_haptics, wlx_input_state, wlx_panel_modify, wvr_display_create,
|
||||||
|
wvr_display_get, wvr_display_list, wvr_display_remove, wvr_display_set_visible,
|
||||||
|
wvr_display_window_list, wvr_process_get, wvr_process_launch, wvr_process_list,
|
||||||
|
wvr_process_terminate, wvr_window_set_visible,
|
||||||
|
};
|
||||||
|
|
||||||
mod helper;
|
mod helper;
|
||||||
|
|
||||||
|
|
||||||
#[tokio::main(flavor = "current_thread")]
|
#[tokio::main(flavor = "current_thread")]
|
||||||
async fn main() -> ExitCode {
|
async fn main() -> ExitCode {
|
||||||
env_logger::init_from_env(Env::default().default_filter_or("info"));
|
env_logger::init_from_env(Env::default().default_filter_or("info"));
|
||||||
let args = Args::parse();
|
let args = Args::parse();
|
||||||
|
|
||||||
let mut state = WayVRClientState {
|
let mut state = WayVRClientState {
|
||||||
wayvr_client : WayVRClient::new(&format!("wayvrctl-{}", process::id())).await.inspect_err(|e| {
|
wayvr_client: WayVRClient::new(&format!("wayvrctl-{}", process::id()))
|
||||||
|
.await
|
||||||
|
.inspect_err(|e| {
|
||||||
log::error!("Failed to initialize WayVR connection: {e:?}");
|
log::error!("Failed to initialize WayVR connection: {e:?}");
|
||||||
process::exit(1);
|
process::exit(1);
|
||||||
}).unwrap(),
|
})
|
||||||
|
.unwrap(),
|
||||||
serial_generator: ipc::SerialGenerator::new(),
|
serial_generator: ipc::SerialGenerator::new(),
|
||||||
pretty_print: args.pretty,
|
pretty_print: args.pretty,
|
||||||
};
|
};
|
||||||
|
|
||||||
let maybe_err = if let Subcommands::Batch {fail_fast} = args.command {
|
let maybe_err = if let Subcommands::Batch { fail_fast } = args.command {
|
||||||
run_batch(&mut state, fail_fast).await
|
run_batch(&mut state, fail_fast).await
|
||||||
} else {
|
} else {
|
||||||
run_once(&mut state, args).await
|
run_once(&mut state, args).await
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Err(e) = maybe_err{
|
if let Err(e) = maybe_err {
|
||||||
log::error!("{e:?}");
|
log::error!("{e:?}");
|
||||||
return ExitCode::FAILURE;
|
return ExitCode::FAILURE;
|
||||||
} else {
|
} else {
|
||||||
@@ -50,22 +61,22 @@ async fn run_batch(state: &mut WayVRClientState, fail_fast: bool) -> anyhow::Res
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Err(e) = parse_run_line(state, &line).await.with_context(|| format!("error on line {}", line_no + 1)) {
|
if let Err(e) = parse_run_line(state, &line)
|
||||||
|
.await
|
||||||
|
.with_context(|| format!("error on line {}", line_no + 1))
|
||||||
|
{
|
||||||
if fail_fast {
|
if fail_fast {
|
||||||
return Err(e)
|
return Err(e);
|
||||||
} else {
|
} else {
|
||||||
log::error!("{e:?}");
|
log::error!("{e:?}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn parse_run_line(state: &mut WayVRClientState, line: &str) -> anyhow::Result<()> {
|
async fn parse_run_line(state: &mut WayVRClientState, line: &str) -> anyhow::Result<()> {
|
||||||
let mut argv = shell_words::split(&line)
|
let mut argv = shell_words::split(&line).with_context(|| format!("parse error"))?;
|
||||||
.with_context(|| format!("parse error"))
|
|
||||||
?;
|
|
||||||
|
|
||||||
// clap expects argv[0] to be the binary name
|
// clap expects argv[0] to be the binary name
|
||||||
argv.insert(0, env!("CARGO_PKG_NAME").to_string());
|
argv.insert(0, env!("CARGO_PKG_NAME").to_string());
|
||||||
@@ -84,8 +95,21 @@ async fn run_once(state: &mut WayVRClientState, args: Args) -> anyhow::Result<()
|
|||||||
Subcommands::InputState => {
|
Subcommands::InputState => {
|
||||||
wlx_input_state(state).await;
|
wlx_input_state(state).await;
|
||||||
}
|
}
|
||||||
Subcommands::DisplayCreate { width, height, name, scale } => {
|
Subcommands::DisplayCreate {
|
||||||
wvr_display_create(state, width, height, name, scale, packet_client::AttachTo::None).await;
|
width,
|
||||||
|
height,
|
||||||
|
name,
|
||||||
|
scale,
|
||||||
|
} => {
|
||||||
|
wvr_display_create(
|
||||||
|
state,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
name,
|
||||||
|
scale,
|
||||||
|
packet_client::AttachTo::None,
|
||||||
|
)
|
||||||
|
.await;
|
||||||
}
|
}
|
||||||
Subcommands::DisplayList => {
|
Subcommands::DisplayList => {
|
||||||
wvr_display_list(state).await;
|
wvr_display_list(state).await;
|
||||||
@@ -102,11 +126,17 @@ async fn run_once(state: &mut WayVRClientState, args: Args) -> anyhow::Result<()
|
|||||||
let handle = serde_json::from_str(&handle).context("Invalid handle")?;
|
let handle = serde_json::from_str(&handle).context("Invalid handle")?;
|
||||||
wvr_display_remove(state, handle).await;
|
wvr_display_remove(state, handle).await;
|
||||||
}
|
}
|
||||||
Subcommands::DisplaySetVisible { handle, visible_0_or_1 } => {
|
Subcommands::DisplaySetVisible {
|
||||||
|
handle,
|
||||||
|
visible_0_or_1,
|
||||||
|
} => {
|
||||||
let handle = serde_json::from_str(&handle).context("Invalid handle")?;
|
let handle = serde_json::from_str(&handle).context("Invalid handle")?;
|
||||||
wvr_display_set_visible(state, handle, visible_0_or_1 != 0).await;
|
wvr_display_set_visible(state, handle, visible_0_or_1 != 0).await;
|
||||||
}
|
}
|
||||||
Subcommands::WindowSetVisible { handle, visible_0_or_1 } => {
|
Subcommands::WindowSetVisible {
|
||||||
|
handle,
|
||||||
|
visible_0_or_1,
|
||||||
|
} => {
|
||||||
let handle = serde_json::from_str(&handle).context("Invalid handle")?;
|
let handle = serde_json::from_str(&handle).context("Invalid handle")?;
|
||||||
wvr_window_set_visible(state, handle, visible_0_or_1 != 0).await;
|
wvr_window_set_visible(state, handle, visible_0_or_1 != 0).await;
|
||||||
}
|
}
|
||||||
@@ -121,20 +151,44 @@ async fn run_once(state: &mut WayVRClientState, args: Args) -> anyhow::Result<()
|
|||||||
let handle = serde_json::from_str(&handle).context("Invalid handle")?;
|
let handle = serde_json::from_str(&handle).context("Invalid handle")?;
|
||||||
wvr_process_terminate(state, handle).await;
|
wvr_process_terminate(state, handle).await;
|
||||||
}
|
}
|
||||||
Subcommands::ProcessLaunch { exec, name, env, target_display, args } => {
|
Subcommands::ProcessLaunch {
|
||||||
|
exec,
|
||||||
|
name,
|
||||||
|
env,
|
||||||
|
target_display,
|
||||||
|
args,
|
||||||
|
} => {
|
||||||
let handle = serde_json::from_str(&target_display).context("Invalid target_display")?;
|
let handle = serde_json::from_str(&target_display).context("Invalid target_display")?;
|
||||||
wvr_process_launch(state, exec, name, env, handle, args, HashMap::new()).await;
|
wvr_process_launch(state, exec, name, env, handle, args, HashMap::new()).await;
|
||||||
}
|
}
|
||||||
Subcommands::Haptics { intensity, duration, frequency } => {
|
Subcommands::Haptics {
|
||||||
|
intensity,
|
||||||
|
duration,
|
||||||
|
frequency,
|
||||||
|
} => {
|
||||||
wlx_haptics(state, intensity, duration, frequency).await;
|
wlx_haptics(state, intensity, duration, frequency).await;
|
||||||
}
|
}
|
||||||
Subcommands::PanelModify { overlay, element, command } => {
|
Subcommands::PanelModify {
|
||||||
|
overlay,
|
||||||
|
element,
|
||||||
|
command,
|
||||||
|
} => {
|
||||||
let command = match command {
|
let command = match command {
|
||||||
SubcommandPanelModify::SetText { text } => packet_client::WlxModifyPanelCommand::SetText(text),
|
SubcommandPanelModify::SetText { text } => {
|
||||||
SubcommandPanelModify::SetColor { hex_color } => packet_client::WlxModifyPanelCommand::SetColor(hex_color),
|
packet_client::WlxModifyPanelCommand::SetText(text)
|
||||||
SubcommandPanelModify::SetImage { absolute_path } => packet_client::WlxModifyPanelCommand::SetImage(absolute_path),
|
}
|
||||||
SubcommandPanelModify::SetVisible { visible_0_or_1 } => packet_client::WlxModifyPanelCommand::SetVisible(visible_0_or_1 != 0),
|
SubcommandPanelModify::SetColor { hex_color } => {
|
||||||
SubcommandPanelModify::SetStickyState { sticky_state_0_or_1 } => packet_client::WlxModifyPanelCommand::SetStickyState(sticky_state_0_or_1 != 0),
|
packet_client::WlxModifyPanelCommand::SetColor(hex_color)
|
||||||
|
}
|
||||||
|
SubcommandPanelModify::SetImage { absolute_path } => {
|
||||||
|
packet_client::WlxModifyPanelCommand::SetImage(absolute_path)
|
||||||
|
}
|
||||||
|
SubcommandPanelModify::SetVisible { visible_0_or_1 } => {
|
||||||
|
packet_client::WlxModifyPanelCommand::SetVisible(visible_0_or_1 != 0)
|
||||||
|
}
|
||||||
|
SubcommandPanelModify::SetStickyState {
|
||||||
|
sticky_state_0_or_1,
|
||||||
|
} => packet_client::WlxModifyPanelCommand::SetStickyState(sticky_state_0_or_1 != 0),
|
||||||
};
|
};
|
||||||
|
|
||||||
wlx_panel_modify(state, overlay, element, command).await;
|
wlx_panel_modify(state, overlay, element, command).await;
|
||||||
@@ -143,7 +197,6 @@ async fn run_once(state: &mut WayVRClientState, args: Args) -> anyhow::Result<()
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// A command-line interface for WayVR IPC
|
/// A command-line interface for WayVR IPC
|
||||||
#[derive(clap::Parser, Debug)]
|
#[derive(clap::Parser, Debug)]
|
||||||
#[command(version, about, long_about = None)]
|
#[command(version, about, long_about = None)]
|
||||||
@@ -168,13 +221,12 @@ enum Subcommands {
|
|||||||
/// Get the positions of HMD & controllers
|
/// Get the positions of HMD & controllers
|
||||||
InputState,
|
InputState,
|
||||||
/// Create a new WayVR display
|
/// Create a new WayVR display
|
||||||
DisplayCreate{
|
DisplayCreate {
|
||||||
width: u16,
|
width: u16,
|
||||||
height: u16,
|
height: u16,
|
||||||
name: String,
|
name: String,
|
||||||
#[arg(short, long)]
|
#[arg(short, long)]
|
||||||
scale: Option<f32>,
|
scale: Option<f32>,
|
||||||
|
|
||||||
//attach_to: packet_client::AttachTo,
|
//attach_to: packet_client::AttachTo,
|
||||||
},
|
},
|
||||||
/// List WayVR displays
|
/// List WayVR displays
|
||||||
@@ -202,7 +254,6 @@ enum Subcommands {
|
|||||||
},
|
},
|
||||||
|
|
||||||
// DisplaySetLayout skipped
|
// DisplaySetLayout skipped
|
||||||
|
|
||||||
/// Change the visibility of a window on a WayVR display
|
/// Change the visibility of a window on a WayVR display
|
||||||
WindowSetVisible {
|
WindowSetVisible {
|
||||||
/// A JSON window handle returned by DisplayWindowList
|
/// A JSON window handle returned by DisplayWindowList
|
||||||
@@ -213,7 +264,6 @@ enum Subcommands {
|
|||||||
ProcessGet {
|
ProcessGet {
|
||||||
/// A JSON process handle returned by ProcessList or ProcessLaunch
|
/// A JSON process handle returned by ProcessList or ProcessLaunch
|
||||||
handle: String,
|
handle: String,
|
||||||
|
|
||||||
},
|
},
|
||||||
/// List all processes managed by WayVR
|
/// List all processes managed by WayVR
|
||||||
ProcessList,
|
ProcessList,
|
||||||
@@ -235,7 +285,7 @@ enum Subcommands {
|
|||||||
Haptics {
|
Haptics {
|
||||||
#[arg(short, long, default_value = "0.25")]
|
#[arg(short, long, default_value = "0.25")]
|
||||||
intensity: f32,
|
intensity: f32,
|
||||||
#[arg(short, long , default_value = "0.1")]
|
#[arg(short, long, default_value = "0.1")]
|
||||||
duration: f32,
|
duration: f32,
|
||||||
#[arg(short, long, default_value = "0.1")]
|
#[arg(short, long, default_value = "0.1")]
|
||||||
frequency: f32,
|
frequency: f32,
|
||||||
@@ -249,8 +299,7 @@ enum Subcommands {
|
|||||||
/// Command to execute
|
/// Command to execute
|
||||||
#[command(subcommand)]
|
#[command(subcommand)]
|
||||||
command: SubcommandPanelModify,
|
command: SubcommandPanelModify,
|
||||||
}
|
},
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(clap::Parser, Debug)]
|
#[derive(clap::Parser, Debug)]
|
||||||
@@ -271,11 +320,7 @@ enum SubcommandPanelModify {
|
|||||||
absolute_path: String,
|
absolute_path: String,
|
||||||
},
|
},
|
||||||
/// Set the visibility of a <div>, <rectangle>, <label>, <sprite> or <image>
|
/// Set the visibility of a <div>, <rectangle>, <label>, <sprite> or <image>
|
||||||
SetVisible {
|
SetVisible { visible_0_or_1: u8 },
|
||||||
visible_0_or_1: u8,
|
|
||||||
},
|
|
||||||
/// Set the sticky state of a <Button>. Intended for buttons without `sticky="1"`.
|
/// Set the sticky state of a <Button>. Intended for buttons without `sticky="1"`.
|
||||||
SetStickyState {
|
SetStickyState { sticky_state_0_or_1: u8 },
|
||||||
sticky_state_0_or_1: u8,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,25 +1,24 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
animation::{Animation, AnimationEasing},
|
animation::{Animation, AnimationEasing},
|
||||||
assets::AssetPath,
|
assets::AssetPath,
|
||||||
components::{self, tooltip::ComponentTooltip, Component, ComponentBase, ComponentTrait, RefreshData},
|
components::{self, Component, ComponentBase, ComponentTrait, RefreshData, tooltip::ComponentTooltip},
|
||||||
drawing::{self, Boundary, Color},
|
drawing::{self, Boundary, Color},
|
||||||
event::{CallbackDataCommon, EventListenerCollection, EventListenerID, EventListenerKind},
|
event::{CallbackDataCommon, EventListenerCollection, EventListenerID, EventListenerKind},
|
||||||
i18n::Translation,
|
i18n::Translation,
|
||||||
layout::{LayoutTask, WidgetID, WidgetPair},
|
layout::{LayoutTask, WidgetID, WidgetPair},
|
||||||
renderer_vk::{
|
renderer_vk::{
|
||||||
text::{
|
text::{
|
||||||
custom_glyph::{CustomGlyphContent, CustomGlyphData},
|
|
||||||
FontWeight, TextStyle,
|
FontWeight, TextStyle,
|
||||||
|
custom_glyph::{CustomGlyphContent, CustomGlyphData},
|
||||||
},
|
},
|
||||||
util::centered_matrix,
|
util::centered_matrix,
|
||||||
},
|
},
|
||||||
widget::{
|
widget::{
|
||||||
self,
|
self, ConstructEssentials, EventResult, WidgetData,
|
||||||
label::{WidgetLabel, WidgetLabelParams},
|
label::{WidgetLabel, WidgetLabelParams},
|
||||||
rectangle::{WidgetRectangle, WidgetRectangleParams},
|
rectangle::{WidgetRectangle, WidgetRectangleParams},
|
||||||
sprite::{WidgetSprite, WidgetSpriteParams},
|
sprite::{WidgetSprite, WidgetSpriteParams},
|
||||||
util::WLength,
|
util::WLength,
|
||||||
ConstructEssentials, EventResult, WidgetData,
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use glam::{Mat4, Vec3};
|
use glam::{Mat4, Vec3};
|
||||||
@@ -28,7 +27,7 @@ use std::{
|
|||||||
rc::Rc,
|
rc::Rc,
|
||||||
time::{Duration, Instant},
|
time::{Duration, Instant},
|
||||||
};
|
};
|
||||||
use taffy::{prelude::length, AlignItems, JustifyContent};
|
use taffy::{AlignItems, JustifyContent, prelude::length};
|
||||||
|
|
||||||
pub struct Params<'a> {
|
pub struct Params<'a> {
|
||||||
pub text: Option<Translation>, // if unset, label will not be populated
|
pub text: Option<Translation>, // if unset, label will not be populated
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use std::{cell::RefCell, rc::Rc};
|
use std::{cell::RefCell, rc::Rc};
|
||||||
use taffy::{
|
use taffy::{
|
||||||
prelude::{length, percent},
|
|
||||||
AlignItems,
|
AlignItems,
|
||||||
|
prelude::{length, percent},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
@@ -13,10 +13,10 @@ use crate::{
|
|||||||
layout::{self, WidgetID, WidgetPair},
|
layout::{self, WidgetID, WidgetPair},
|
||||||
renderer_vk::text::{FontWeight, TextStyle},
|
renderer_vk::text::{FontWeight, TextStyle},
|
||||||
widget::{
|
widget::{
|
||||||
|
ConstructEssentials, EventResult,
|
||||||
label::{WidgetLabel, WidgetLabelParams},
|
label::{WidgetLabel, WidgetLabelParams},
|
||||||
rectangle::{WidgetRectangle, WidgetRectangleParams},
|
rectangle::{WidgetRectangle, WidgetRectangleParams},
|
||||||
util::WLength,
|
util::WLength,
|
||||||
ConstructEssentials, EventResult,
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -18,11 +18,11 @@ use crate::{
|
|||||||
util,
|
util,
|
||||||
},
|
},
|
||||||
widget::{
|
widget::{
|
||||||
|
ConstructEssentials, EventResult,
|
||||||
div::WidgetDiv,
|
div::WidgetDiv,
|
||||||
label::{WidgetLabel, WidgetLabelParams},
|
label::{WidgetLabel, WidgetLabelParams},
|
||||||
rectangle::{WidgetRectangle, WidgetRectangleParams},
|
rectangle::{WidgetRectangle, WidgetRectangleParams},
|
||||||
util::WLength,
|
util::WLength,
|
||||||
ConstructEssentials, EventResult,
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ use crate::{
|
|||||||
globals::Globals,
|
globals::Globals,
|
||||||
layout::Widget,
|
layout::Widget,
|
||||||
renderer_vk::text::{
|
renderer_vk::text::{
|
||||||
custom_glyph::{CustomGlyph, CustomGlyphData},
|
|
||||||
TextShadow,
|
TextShadow,
|
||||||
|
custom_glyph::{CustomGlyph, CustomGlyphData},
|
||||||
},
|
},
|
||||||
stack::{self, ScissorBoundary, ScissorStack, TransformStack},
|
stack::{self, ScissorBoundary, ScissorStack, TransformStack},
|
||||||
widget::{self, ScrollbarInfo, WidgetState},
|
widget::{self, ScrollbarInfo, WidgetState},
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
assets::AssetPath,
|
assets::AssetPath,
|
||||||
components::{button, tooltip, Component},
|
components::{Component, button, tooltip},
|
||||||
drawing::Color,
|
drawing::Color,
|
||||||
i18n::Translation,
|
i18n::Translation,
|
||||||
layout::WidgetID,
|
layout::WidgetID,
|
||||||
parser::{
|
parser::{
|
||||||
parse_check_f32, parse_check_i32, parse_children, parse_f32, print_invalid_attrib, process_component,
|
AttribPair, ParserContext, ParserFile, parse_check_f32, parse_check_i32, parse_children, parse_f32,
|
||||||
|
print_invalid_attrib, process_component,
|
||||||
style::{parse_color_opt, parse_round, parse_style, parse_text_style},
|
style::{parse_color_opt, parse_round, parse_style, parse_text_style},
|
||||||
AttribPair, ParserContext, ParserFile,
|
|
||||||
},
|
},
|
||||||
widget::util::WLength,
|
widget::util::WLength,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ mod widget_rectangle;
|
|||||||
mod widget_sprite;
|
mod widget_sprite;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
assets::{normalize_path, AssetPath, AssetPathOwned},
|
assets::{AssetPath, AssetPathOwned, normalize_path},
|
||||||
components::{Component, ComponentWeak},
|
components::{Component, ComponentWeak},
|
||||||
drawing::{self},
|
drawing::{self},
|
||||||
globals::WguiGlobals,
|
globals::WguiGlobals,
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ use taffy::{
|
|||||||
use crate::{
|
use crate::{
|
||||||
drawing,
|
drawing,
|
||||||
parser::{
|
parser::{
|
||||||
is_percent, parse_color_hex, parse_f32, parse_percent, parse_size_unit, parse_val, print_invalid_attrib,
|
AttribPair, is_percent, parse_color_hex, parse_f32, parse_percent, parse_size_unit, parse_val,
|
||||||
print_invalid_value, AttribPair,
|
print_invalid_attrib, print_invalid_value,
|
||||||
},
|
},
|
||||||
renderer_vk::text::{FontWeight, HorizontalAlign, TextStyle},
|
renderer_vk::text::{FontWeight, HorizontalAlign, TextStyle},
|
||||||
widget::util::WLength,
|
widget::util::WLength,
|
||||||
|
|||||||
@@ -2,9 +2,8 @@ use crate::{
|
|||||||
assets::AssetPath,
|
assets::AssetPath,
|
||||||
layout::WidgetID,
|
layout::WidgetID,
|
||||||
parser::{
|
parser::{
|
||||||
parse_children, parse_widget_universal, print_invalid_attrib,
|
AttribPair, ParserContext, ParserFile, parse_children, parse_widget_universal, print_invalid_attrib,
|
||||||
style::{parse_color, parse_round, parse_style},
|
style::{parse_color, parse_round, parse_style},
|
||||||
AttribPair, ParserContext, ParserFile,
|
|
||||||
},
|
},
|
||||||
renderer_vk::text::custom_glyph::{CustomGlyphContent, CustomGlyphData},
|
renderer_vk::text::custom_glyph::{CustomGlyphContent, CustomGlyphData},
|
||||||
widget::image::{WidgetImage, WidgetImageParams},
|
widget::image::{WidgetImage, WidgetImageParams},
|
||||||
|
|||||||
@@ -2,9 +2,8 @@ use crate::{
|
|||||||
drawing::GradientMode,
|
drawing::GradientMode,
|
||||||
layout::WidgetID,
|
layout::WidgetID,
|
||||||
parser::{
|
parser::{
|
||||||
parse_children, parse_widget_universal, print_invalid_attrib,
|
AttribPair, ParserContext, ParserFile, parse_children, parse_widget_universal, print_invalid_attrib,
|
||||||
style::{parse_color, parse_round, parse_style},
|
style::{parse_color, parse_round, parse_style},
|
||||||
AttribPair, ParserContext, ParserFile,
|
|
||||||
},
|
},
|
||||||
widget::rectangle::{WidgetRectangle, WidgetRectangleParams},
|
widget::rectangle::{WidgetRectangle, WidgetRectangleParams},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
assets::AssetPath,
|
assets::AssetPath,
|
||||||
layout::WidgetID,
|
layout::WidgetID,
|
||||||
parser::{parse_children, parse_widget_universal, style::parse_style, AttribPair, ParserContext, ParserFile},
|
parser::{AttribPair, ParserContext, ParserFile, parse_children, parse_widget_universal, style::parse_style},
|
||||||
renderer_vk::text::custom_glyph::{CustomGlyphContent, CustomGlyphData},
|
renderer_vk::text::custom_glyph::{CustomGlyphContent, CustomGlyphData},
|
||||||
widget::sprite::{WidgetSprite, WidgetSpriteParams},
|
widget::sprite::{WidgetSprite, WidgetSpriteParams},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,22 +2,22 @@ use std::{cell::RefCell, rc::Rc, sync::Arc};
|
|||||||
|
|
||||||
use cosmic_text::Buffer;
|
use cosmic_text::Buffer;
|
||||||
use glam::{Mat4, Vec2, Vec3};
|
use glam::{Mat4, Vec2, Vec3};
|
||||||
use slotmap::{new_key_type, SlotMap};
|
use slotmap::{SlotMap, new_key_type};
|
||||||
use vulkano::pipeline::graphics::viewport;
|
use vulkano::pipeline::graphics::viewport;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
drawing::{self},
|
drawing::{self},
|
||||||
font_config,
|
font_config,
|
||||||
gfx::{cmd::GfxCommandBuffer, WGfx},
|
gfx::{WGfx, cmd::GfxCommandBuffer},
|
||||||
renderer_vk::image::{ImagePipeline, ImageRenderer},
|
renderer_vk::image::{ImagePipeline, ImageRenderer},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
rect::{RectPipeline, RectRenderer},
|
rect::{RectPipeline, RectRenderer},
|
||||||
text::{
|
text::{
|
||||||
|
DEFAULT_METRICS, SWASH_CACHE, TextArea, TextBounds,
|
||||||
text_atlas::{TextAtlas, TextPipeline},
|
text_atlas::{TextAtlas, TextPipeline},
|
||||||
text_renderer::TextRenderer,
|
text_renderer::TextRenderer,
|
||||||
TextArea, TextBounds, DEFAULT_METRICS, SWASH_CACHE,
|
|
||||||
},
|
},
|
||||||
viewport::Viewport,
|
viewport::Viewport,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -14,10 +14,10 @@ use vulkano::{
|
|||||||
use crate::{
|
use crate::{
|
||||||
drawing::{Boundary, ImagePrimitive},
|
drawing::{Boundary, ImagePrimitive},
|
||||||
gfx::{
|
gfx::{
|
||||||
|
BLEND_ALPHA, WGfx,
|
||||||
cmd::GfxCommandBuffer,
|
cmd::GfxCommandBuffer,
|
||||||
pass::WGfxPass,
|
pass::WGfxPass,
|
||||||
pipeline::{WGfxPipeline, WPipelineCreateInfo},
|
pipeline::{WGfxPipeline, WPipelineCreateInfo},
|
||||||
WGfx, BLEND_ALPHA,
|
|
||||||
},
|
},
|
||||||
renderer_vk::{
|
renderer_vk::{
|
||||||
model_buffer::ModelBuffer,
|
model_buffer::ModelBuffer,
|
||||||
|
|||||||
@@ -10,10 +10,10 @@ use vulkano::{
|
|||||||
use crate::{
|
use crate::{
|
||||||
drawing::{Boundary, Rectangle},
|
drawing::{Boundary, Rectangle},
|
||||||
gfx::{
|
gfx::{
|
||||||
|
BLEND_ALPHA, WGfx,
|
||||||
cmd::GfxCommandBuffer,
|
cmd::GfxCommandBuffer,
|
||||||
pass::WGfxPass,
|
pass::WGfxPass,
|
||||||
pipeline::{WGfxPipeline, WPipelineCreateInfo},
|
pipeline::{WGfxPipeline, WPipelineCreateInfo},
|
||||||
WGfx, BLEND_ALPHA,
|
|
||||||
},
|
},
|
||||||
renderer_vk::model_buffer::ModelBuffer,
|
renderer_vk::model_buffer::ModelBuffer,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
use std::{
|
use std::{
|
||||||
f32,
|
f32,
|
||||||
sync::{
|
sync::{
|
||||||
atomic::{AtomicUsize, Ordering},
|
|
||||||
Arc,
|
Arc,
|
||||||
|
atomic::{AtomicUsize, Ordering},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ use crate::{
|
|||||||
globals::Globals,
|
globals::Globals,
|
||||||
layout::WidgetID,
|
layout::WidgetID,
|
||||||
renderer_vk::text::custom_glyph::CustomGlyphData,
|
renderer_vk::text::custom_glyph::CustomGlyphData,
|
||||||
widget::{util::WLength, WidgetStateFlags},
|
widget::{WidgetStateFlags, util::WLength},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{WidgetObj, WidgetState};
|
use super::{WidgetObj, WidgetState};
|
||||||
|
|||||||
@@ -206,11 +206,7 @@ impl EventResult {
|
|||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn merge(self, other: Self) -> Self {
|
pub fn merge(self, other: Self) -> Self {
|
||||||
if self > other {
|
if self > other { self } else { other }
|
||||||
self
|
|
||||||
} else {
|
|
||||||
other
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ use crate::{
|
|||||||
drawing::{self, GradientMode, PrimitiveExtent},
|
drawing::{self, GradientMode, PrimitiveExtent},
|
||||||
event::CallbackDataCommon,
|
event::CallbackDataCommon,
|
||||||
layout::WidgetID,
|
layout::WidgetID,
|
||||||
widget::{util::WLength, WidgetStateFlags},
|
widget::{WidgetStateFlags, util::WLength},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{WidgetObj, WidgetState};
|
use super::{WidgetObj, WidgetState};
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ use crate::{
|
|||||||
globals::Globals,
|
globals::Globals,
|
||||||
layout::WidgetID,
|
layout::WidgetID,
|
||||||
renderer_vk::text::{
|
renderer_vk::text::{
|
||||||
custom_glyph::{CustomGlyph, CustomGlyphData},
|
|
||||||
DEFAULT_METRICS,
|
DEFAULT_METRICS,
|
||||||
|
custom_glyph::{CustomGlyph, CustomGlyphData},
|
||||||
},
|
},
|
||||||
widget::WidgetStateFlags,
|
widget::WidgetStateFlags,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -33,7 +33,6 @@ use crate::{
|
|||||||
use super::timer::GuiTimer;
|
use super::timer::GuiTimer;
|
||||||
|
|
||||||
pub mod button;
|
pub mod button;
|
||||||
mod helper;
|
|
||||||
mod label;
|
mod label;
|
||||||
|
|
||||||
const DEFAULT_MAX_SIZE: f32 = 2048.0;
|
const DEFAULT_MAX_SIZE: f32 = 2048.0;
|
||||||
|
|||||||
Reference in New Issue
Block a user