From 612c8ccfa5b3b573bf73bf76aefb79bcaf05c982 Mon Sep 17 00:00:00 2001 From: csd4ni3l Date: Tue, 23 Dec 2025 19:51:06 +0100 Subject: [PATCH] Add JSON file loading and new resmut for storing it but nothing much yet --- .gitignore | 1 + Cargo.lock | 6 +- Cargo.toml | 2 + src/main.rs | 173 +++++++++++++++++++++++++++++++++++++++++++++++++--- 4 files changed, 171 insertions(+), 11 deletions(-) diff --git a/.gitignore b/.gitignore index ea8c4bf..002497b 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ /target +data.json diff --git a/Cargo.lock b/Cargo.lock index 3a21db0..b5f9dcb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4820,9 +4820,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.145" +version = "1.0.146" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" +checksum = "217ca874ae0207aac254aa02c957ded05585a90892cc8d87f9e5fa49669dadd8" dependencies = [ "itoa", "memchr", @@ -4947,6 +4947,8 @@ dependencies = [ "rand", "rfd", "rodio 0.21.1", + "serde", + "serde_json", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index bced995..81e6877 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,6 +9,8 @@ cpal = "0.17.0" rand = "0.9.2" rfd = "0.16.0" rodio = { version = "0.21.1", features = ["mp3", "wav", "flac", "vorbis"] } +serde = "1.0.228" +serde_json = "1.0.146" [dependencies.bevy] version = "0.17.3" diff --git a/src/main.rs b/src/main.rs index 23374f5..0acf66c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,22 +1,177 @@ -use bevy::prelude::*; -use bevy_egui::{egui, EguiContexts, EguiPlugin, EguiPrimaryContextPass}; +use bevy::{ + log::{Level, LogPlugin}, + prelude::*, +}; + +use std::collections::HashMap; + +use serde::{Deserialize, Serialize}; + +use bevy_egui::{ + EguiContextSettings, EguiContexts, EguiPlugin, EguiPrimaryContextPass, EguiStartupSet, egui, +}; +#[derive(Serialize, Deserialize)] +struct JSONData { + tabs: Vec, +} + +#[derive(Resource)] +struct FileData { + loaded_files: HashMap>, + json_data: JSONData, +} fn main() { App::new() - .add_plugins(DefaultPlugins) + .insert_resource(ClearColor(Color::BLACK)) + .add_plugins( + DefaultPlugins + .set(LogPlugin { + filter: "warn,ui=info".to_string(), + level: Level::INFO, + ..Default::default() + }) + .set(WindowPlugin { + primary_window: Some(Window { + // You may want this set to `true` if you need virtual keyboard work in mobile browsers. + prevent_default_event_handling: false, + ..default() + }), + ..default() + }), + ) .add_plugins(EguiPlugin::default()) - .add_systems(Startup, setup_camera_system) - .add_systems(EguiPrimaryContextPass, ui_example_system) + .insert_resource(FileData { + loaded_files: HashMap::new(), + json_data: JSONData { tabs: Vec::new() }, + }) + .add_systems( + PreStartup, + setup_camera_system.before(EguiStartupSet::InitContexts), + ) + .add_systems(Startup, load_json_system) + .add_systems( + EguiPrimaryContextPass, + (ui_system, update_ui_scale_factor_system), + ) .run(); } +fn load_json_system(mut file_data: ResMut) { + if std::fs::exists("data.json").expect("Failed to check existence of JSON file") { + let data = std::fs::read_to_string("data.json").expect("Failed to read JSON"); + file_data.json_data = serde_json::from_str(&data).expect("Failed to load JSON"); + + let tabs = file_data.json_data.tabs.clone(); + file_data.loaded_files.clear(); + + for tab in tabs { + file_data.loaded_files.insert(tab.clone(), Vec::new()); + if std::fs::exists(tab.clone()).expect("Failed to check existence of tab directory.") { + file_data.loaded_files.insert( + tab.clone(), + std::fs::read_dir(tab) + .expect("Failed to read directory") + .filter_map(|entry| { + entry.ok().and_then(|e| { + let path = e.path(); + if path.is_file() { + path.to_str().map(|s| s.to_string()) + } else { + None + } + }) + }) + .collect(), + ); + } + } + } +} + fn setup_camera_system(mut commands: Commands) { commands.spawn(Camera2d); } -fn ui_example_system(mut contexts: EguiContexts) -> Result { - egui::Window::new("Hello").show(contexts.ctx_mut()?, |ui| { - ui.label("world"); +fn update_ui_scale_factor_system( + keyboard_input: Res>, + mut toggle_scale_factor: Local>, + egui_context: Single<(&mut EguiContextSettings, &Camera)>, +) { + let (mut egui_settings, camera) = egui_context.into_inner(); + if keyboard_input.just_pressed(KeyCode::Slash) || toggle_scale_factor.is_none() { + *toggle_scale_factor = Some(!toggle_scale_factor.unwrap_or(true)); + + let scale_factor = if toggle_scale_factor.unwrap() { + 1.0 + } else { + 1.0 / camera.target_scaling_factor().unwrap_or(1.0) + }; + egui_settings.scale_factor = scale_factor; + } +} + +fn ui_system(mut contexts: EguiContexts, mut file_data: ResMut) -> Result { + let ctx = contexts.ctx_mut()?; + + egui::TopBottomPanel::top("top_panel").show(ctx, |ui| { + ui.heading("csd4ni3l Soundboard"); }); + + egui::CentralPanel::default().show(ctx, |ui| { + ui.label("The app!"); + }); + + egui::SidePanel::right("tools").show(ctx, |ui| { + ui.heading("Tools"); + + ui.separator(); + + if ui + .add_sized( + [ui.available_width(), 40.0], + egui::Button::new("Add folder"), + ) + .clicked() + { + if let Some(folder) = rfd::FileDialog::new().pick_folder() { + if let Some(path_str) = folder.to_str() { + println!("Selected: {}", path_str); + file_data.json_data.tabs.push(path_str.to_string()); + std::fs::write( + "data.json", + serde_json::to_string(&file_data.json_data) + .expect("Could not convert JSON to string"), + ) + .expect("Could not write to JSON file"); + load_json_system(file_data); + } else { + println!("Invalid path encoding!"); + } + } + } + + if ui + .add_sized( + [ui.available_width(), 40.0], + egui::Button::new("Reload content"), + ) + .clicked() + { + load_json_system(file_data); + println!("Reloaded content"); + } + + if ui + .add_sized( + [ui.available_width(), 40.0], + egui::Button::new("Youtube downloader"), + ) + .clicked() + { + println!("Youtube downloader!"); + } + }); + Ok(()) -} \ No newline at end of file +}