This commit is contained in:
Nicola Guerrera
2023-03-01 10:56:06 +01:00
parent abcf78797c
commit fd03171429
3 changed files with 45 additions and 35 deletions

View File

@@ -17,7 +17,9 @@ use stardust_xr_molecules::touch_plane::TouchPlane;
use std::f32::consts::PI; use std::f32::consts::PI;
use tween::TweenTime; use tween::TweenTime;
const APP_SIZE: f32 = 0.065; const APP_SIZE: f32 = 0.06;
const PADDING: f32 = 0.005;
#[derive(Clone)] #[derive(Clone)]
struct Hex { struct Hex {
q: isize, q: isize,
@@ -41,9 +43,9 @@ impl Hex {
} }
fn get_coords(&self) -> [f32; 3] { fn get_coords(&self) -> [f32; 3] {
let x = 3.0 / 2.0 * APP_SIZE / 2.0 * (-self.q - self.s).to_f32(); let x = 3.0 / 2.0 * (APP_SIZE + PADDING) / 2.0 * (-self.q - self.s).to_f32();
let y = let y = 3.0_f32.sqrt() * (APP_SIZE + PADDING) / 2.0
3.0_f32.sqrt() * APP_SIZE / 2.0 * ((-self.q - self.s).to_f32() / 2.0 + self.s.to_f32()); * ((-self.q - self.s).to_f32() / 2.0 + self.s.to_f32());
[x, y, 0.0] [x, y, 0.0]
} }
@@ -126,7 +128,6 @@ impl RootHandler for AppHexGrid {
fn frame(&mut self, info: FrameInfo) { fn frame(&mut self, info: FrameInfo) {
self.button.touch_plane.update(); self.button.touch_plane.update();
if self.button.touch_plane.touch_started() { if self.button.touch_plane.touch_started() {
dbg!("Touch started");
let color = [0.0, 1.0, 0.0, 1.0]; let color = [0.0, 1.0, 0.0, 1.0];
self.button self.button
.model .model
@@ -161,9 +162,9 @@ impl App {
) -> Option<Self> { ) -> Option<Self> {
let position = position.into(); let position = position.into();
let style = TextStyle { let style = TextStyle {
character_height: APP_SIZE * 0.1, character_height: (APP_SIZE + PADDING) * 0.1,
bounds: Some(Bounds { bounds: Some(Bounds {
bounds: [APP_SIZE; 2].into(), bounds: [(APP_SIZE + PADDING); 2].into(),
fit: TextFit::Wrap, fit: TextFit::Wrap,
bounds_align: Alignment::XCenter | Alignment::YCenter, bounds_align: Alignment::XCenter | Alignment::YCenter,
}), }),
@@ -174,7 +175,7 @@ impl App {
ProtoStar::create_from_desktop_file(parent, position, desktop_file.clone()).ok()?; ProtoStar::create_from_desktop_file(parent, position, desktop_file.clone()).ok()?;
let text = Text::create( let text = Text::create(
protostar.content_parent(), protostar.content_parent(),
Transform::from_position_rotation([0.0, 0.0, 0.004], Quat::from_rotation_y(3.14)), Transform::from_position_rotation([0.0, 0.0, 0.004], Quat::from_rotation_y(PI)),
desktop_file.name.as_deref().unwrap_or("Unknown"), desktop_file.name.as_deref().unwrap_or("Unknown"),
style, style,
) )
@@ -201,8 +202,8 @@ impl Button {
let touch_plane = TouchPlane::new( let touch_plane = TouchPlane::new(
client.get_root(), client.get_root(),
Transform::default(), Transform::default(),
[APP_SIZE / 2.0, APP_SIZE / 2.0], [(APP_SIZE + PADDING) / 2.0; 2],
APP_SIZE / 2.0, (APP_SIZE + PADDING) / 2.0,
)?; )?;
let model = Model::create( let model = Model::create(
client.get_root(), client.get_root(),

View File

@@ -19,12 +19,15 @@ use std::process::{Command, Stdio};
use std::{f32::consts::PI, sync::Arc}; use std::{f32::consts::PI, sync::Arc};
use tween::{QuartInOut, Tweener}; use tween::{QuartInOut, Tweener};
const MODEL_SCALE: f32 = 0.03;
const ACTIVATION_DISTANCE: f32 = 1.0;
fn model_from_icon(parent: &Spatial, icon: &Icon) -> Result<Model> { fn model_from_icon(parent: &Spatial, icon: &Icon) -> Result<Model> {
return match &icon.icon_type { return match &icon.icon_type {
IconType::Png => { IconType::Png => {
let t = Transform::from_rotation_scale( let t = Transform::from_rotation_scale(
Quat::from_rotation_x(PI / 2.0) * Quat::from_rotation_y(PI), Quat::from_rotation_x(PI / 2.0) * Quat::from_rotation_y(PI),
[0.03, 0.03, 0.03], [MODEL_SCALE; 3],
); );
let model = Model::create( let model = Model::create(
@@ -61,9 +64,9 @@ pub struct ProtoStar {
icon: Model, icon: Model,
grabbable_shrink: Option<Tweener<f32, f64, QuartInOut>>, grabbable_shrink: Option<Tweener<f32, f64, QuartInOut>>,
grabbable_grow: Option<Tweener<f32, f64, QuartInOut>>, grabbable_grow: Option<Tweener<f32, f64, QuartInOut>>,
grabbabe_move: Option<Tweener<f32, f64, QuartInOut>>,
execute_command: String, execute_command: String,
currently_shown: bool, currently_shown: bool,
grabbabe_move: Option<Tweener<f32, f64, QuartInOut>>,
} }
impl ProtoStar { impl ProtoStar {
pub fn create_from_desktop_file( pub fn create_from_desktop_file(
@@ -130,8 +133,8 @@ impl ProtoStar {
Ok(Model::create( Ok(Model::create(
grabbable.content_parent(), grabbable.content_parent(),
Transform::from_rotation_scale( Transform::from_rotation_scale(
Quat::from_xyzw(0.0, 0.707, 0.707, 0.0), Quat::from_rotation_x(PI / 2.0) * Quat::from_rotation_y(PI),
[0.03, 0.03, 0.03], [MODEL_SCALE; 3],
), ),
&ResourceID::new_namespaced("protostar", "hexagon/hexagon"), &ResourceID::new_namespaced("protostar", "hexagon/hexagon"),
)?) )?)
@@ -157,9 +160,9 @@ impl ProtoStar {
self.grabbabe_move = Some(Tweener::quart_in_out(1.0, 0.0001, 0.25)); //TODO make the scale a parameter self.grabbabe_move = Some(Tweener::quart_in_out(1.0, 0.0001, 0.25)); //TODO make the scale a parameter
} else { } else {
self.grabbable self.grabbable
.content_parent() .content_parent()
.set_scale(None, Vector3::from([1.0; 3])) .set_scale(None, Vector3::from([1.0; 3]))
.unwrap(); .unwrap();
self.grabbabe_move = Some(Tweener::quart_in_out(0.0001, 1.0, 0.25)); self.grabbabe_move = Some(Tweener::quart_in_out(0.0001, 1.0, 0.25));
} }
self.currently_shown = !self.currently_shown; self.currently_shown = !self.currently_shown;
@@ -167,7 +170,6 @@ impl ProtoStar {
} }
impl RootHandler for ProtoStar { impl RootHandler for ProtoStar {
fn frame(&mut self, info: FrameInfo) { fn frame(&mut self, info: FrameInfo) {
self.grabbable.update(&info); self.grabbable.update(&info);
if let Some(grabbabe_move) = &mut self.grabbabe_move { if let Some(grabbabe_move) = &mut self.grabbabe_move {
@@ -175,14 +177,21 @@ impl RootHandler for ProtoStar {
let scale = grabbabe_move.move_by(info.delta); let scale = grabbabe_move.move_by(info.delta);
self.grabbable self.grabbable
.content_parent() .content_parent()
.set_position(Some(self.client.get_root()), [self.position.x*scale, self.position.y*scale, self.position.z*scale]) .set_position(
Some(self.client.get_root()),
[
self.position.x * scale,
self.position.y * scale,
self.position.z * scale,
],
)
.unwrap(); .unwrap();
} else { } else {
if grabbabe_move.final_value() == 0.0001 { if grabbabe_move.final_value() == 0.0001 {
self.grabbable self.grabbable
.content_parent() .content_parent()
.set_scale(None, Vector3::from([0.001; 3])) .set_scale(None, Vector3::from([0.001; 3]))
.unwrap(); .unwrap();
} }
self.grabbabe_move = None; self.grabbabe_move = None;
} }
@@ -196,7 +205,7 @@ impl RootHandler for ProtoStar {
.unwrap(); .unwrap();
} else { } else {
if self.currently_shown { if self.currently_shown {
self.grabbable_grow = Some(Tweener::quart_in_out(0.0001, 1.0, 0.25)); //TODO make the scale a parameter self.grabbable_grow = Some(Tweener::quart_in_out(0.0001, 1.0, 0.25));
self.grabbable.cancel_angular_velocity(); self.grabbable.cancel_angular_velocity();
self.grabbable.cancel_linear_velocity(); self.grabbable.cancel_linear_velocity();
} }
@@ -231,7 +240,7 @@ impl RootHandler for ProtoStar {
startup_settings startup_settings
.set_root(self.grabbable.content_parent()) .set_root(self.grabbable.content_parent())
.unwrap(); .unwrap();
self.grabbable_shrink = Some(Tweener::quart_in_out(0.03, 0.0001, 0.25)); //TODO make the scale a parameter self.grabbable_shrink = Some(Tweener::quart_in_out(MODEL_SCALE, 0.0001, 0.25));
let distance_future = self let distance_future = self
.grabbable .grabbable
.content_parent() .content_parent()
@@ -243,18 +252,19 @@ impl RootHandler for ProtoStar {
//TODO: split the executable string for the args //TODO: split the executable string for the args
tokio::task::spawn(async move { tokio::task::spawn(async move {
let distance_vector = distance_future.await.ok().unwrap().0; let distance_vector = distance_future.await.ok().unwrap().0;
let distance = let distance = ((distance_vector.x.powi(2) + distance_vector.y.powi(2)).sqrt()
distance_vector.x.abs() + distance_vector.y.abs() + distance_vector.z.abs(); + distance_vector.z.powi(2))
if dbg!(distance) > 1.0 { .sqrt();
if dbg!(distance) > ACTIVATION_DISTANCE {
let future = startup_settings.generate_startup_token().unwrap(); let future = startup_settings.generate_startup_token().unwrap();
std::env::set_var("STARDUST_STARTUP_TOKEN", future.await.unwrap()); std::env::set_var("STARDUST_STARTUP_TOKEN", future.await.unwrap());
let re = Regex::new(r"%[fFuUdDnNickvm]").unwrap(); let re = Regex::new(r"%[fFuUdDnNickvm]").unwrap();
let exec = re.replace_all(&executable, ""); let exec = re.replace_all(&executable, "");
let mut executable_array : Vec<&str> = dbg!(exec.split_whitespace().collect());
unsafe { unsafe {
Command::new(executable_array.remove(0)) Command::new("sh")
.args(executable_array) .arg("-c")
.arg(exec.to_string())
.stdin(Stdio::null()) .stdin(Stdio::null())
.stdout(Stdio::null()) .stdout(Stdio::null())
.stderr(Stdio::null()) .stderr(Stdio::null())

View File

@@ -1,6 +1,7 @@
use cached::proc_macro::cached; use cached::proc_macro::cached;
use color_eyre::eyre::Result; use color_eyre::eyre::Result;
use linicon; use linicon;
use regex::Regex;
use resvg::render; use resvg::render;
use resvg::tiny_skia::{Pixmap, Transform}; use resvg::tiny_skia::{Pixmap, Transform};
use resvg::usvg::{FitTo, Tree}; use resvg::usvg::{FitTo, Tree};
@@ -12,7 +13,6 @@ use std::path::{Path, PathBuf};
use std::str::FromStr; use std::str::FromStr;
use std::{env, fs}; use std::{env, fs};
use walkdir::WalkDir; use walkdir::WalkDir;
use regex::Regex;
fn get_data_dirs() -> Vec<PathBuf> { fn get_data_dirs() -> Vec<PathBuf> {
let xdg_data_dirs_str = std::env::var("XDG_DATA_DIRS").unwrap_or_default(); let xdg_data_dirs_str = std::env::var("XDG_DATA_DIRS").unwrap_or_default();
@@ -88,13 +88,12 @@ pub fn parse_desktop_file(path: PathBuf) -> Result<DesktopFile, String> {
let mut categories = Vec::new(); let mut categories = Vec::new();
let mut icon = None; let mut icon = None;
let mut no_display = false; let mut no_display = false;
let mut desktop_entry_found = false; let mut desktop_entry_found = false;
let re = Regex::new(r"^\[([^\]]*)\]$").unwrap(); let re = Regex::new(r"^\[([^\]]*)\]$").unwrap();
// Loop through each line of the file // Loop through each line of the file
for line in reader.lines() { for line in reader.lines() {
let line = match line { let line = match line {
Ok(line) => line, Ok(line) => line,
Err(err) => return Err(format!("Failed to read line: {}", err)), Err(err) => return Err(format!("Failed to read line: {}", err)),
@@ -105,13 +104,13 @@ pub fn parse_desktop_file(path: PathBuf) -> Result<DesktopFile, String> {
continue; continue;
} }
if let Some(captures) = re.captures(&line){ if let Some(captures) = re.captures(&line) {
let entry = captures.get(1).unwrap(); let entry = captures.get(1).unwrap();
desktop_entry_found = entry.as_str().contains("Desktop Entry"); desktop_entry_found = entry.as_str().contains("Desktop Entry");
} }
if !desktop_entry_found { if !desktop_entry_found {
continue continue;
} }
// Split the line into a key-value pair by looking for the first "=" character // Split the line into a key-value pair by looking for the first "=" character
let parts = line.split_once('='); let parts = line.split_once('=');