Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b7db734cc7 | |||
| 55d96d470d |
686
Cargo.lock
generated
686
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -15,6 +15,8 @@ iced_aw = {version = "0.12.2", default-features = true}
|
||||
iced_fonts = "0.2.1"
|
||||
smol_str = "0.3.2"
|
||||
winapi = {version = "0.3", features = ["wincon", "winuser"]}
|
||||
rfd = "0.15.4"
|
||||
pathdiff = "0.2.3"
|
||||
|
||||
[profile.release]
|
||||
opt-level = 3
|
||||
|
||||
50
src/gui.rs
50
src/gui.rs
@@ -17,9 +17,8 @@ use std::f32::consts::PI;
|
||||
|
||||
use crate::Polymusic;
|
||||
|
||||
pub fn music_view(app: &Polymusic) -> iced::Element<Message> {
|
||||
pub fn music_view(app: &Polymusic) -> iced::Element<'_, Message> {
|
||||
let mut i = 0;
|
||||
let entries = app.all_sounds.clone();
|
||||
//Create all polygon options
|
||||
let polygon_rows: Vec<Element<Message>> = app
|
||||
.music
|
||||
@@ -40,10 +39,14 @@ pub fn music_view(app: &Polymusic) -> iced::Element<Message> {
|
||||
Message::CancelColor(i),
|
||||
move |color| Message::ChooseColor(i, color)
|
||||
),
|
||||
pick_list(entries.clone(), Some(&polygon.sound_name), move |s| {
|
||||
Message::ChangeSound(current_index, s)
|
||||
})
|
||||
.text_size(20),
|
||||
button(text(
|
||||
polygon
|
||||
.sound_name
|
||||
.rsplit(['/', '\\'])
|
||||
.next()
|
||||
.unwrap_or(&polygon.sound_name)
|
||||
))
|
||||
.on_press(Message::ChangeSound(current_index)),
|
||||
]
|
||||
.spacing(20),
|
||||
row![
|
||||
@@ -183,11 +186,6 @@ pub fn music_view(app: &Polymusic) -> iced::Element<Message> {
|
||||
]
|
||||
.spacing(20),
|
||||
column![
|
||||
/*
|
||||
slider(0.0..=app.music.length, self.current_delta, move |f| {
|
||||
Message::ChangeDelta(f)
|
||||
})
|
||||
.step(&app.music.length / 10_000.),*/
|
||||
canvas(&app.music)
|
||||
.height(Length::FillPortion(1))
|
||||
.width(Length::FillPortion(1))
|
||||
@@ -203,41 +201,17 @@ pub fn music_view(app: &Polymusic) -> iced::Element<Message> {
|
||||
.into()
|
||||
}
|
||||
|
||||
pub fn load_file_view(app: &Polymusic) -> iced::Element<Message> {
|
||||
pub fn load_file_view() -> iced::Element<'static, Message> {
|
||||
Container::new(
|
||||
column![
|
||||
text("Polymusic").size(42),
|
||||
row![
|
||||
column![
|
||||
TextInput::new("Name File", &app.file_name_to_creat)
|
||||
.on_input(|new_value| Message::SetFileNameCreat(new_value)),
|
||||
button("Create File").on_press(Message::CreatFile),
|
||||
text(if app.show_warning_message_creat {
|
||||
"Warning: File already exists. Delete it or change the file name!"
|
||||
} else {
|
||||
""
|
||||
})
|
||||
.style(|theme: &Theme| {
|
||||
let palette = theme.extended_palette();
|
||||
|
||||
text::Style {
|
||||
color: Some(palette.danger.strong.color),
|
||||
}
|
||||
},)
|
||||
]
|
||||
column![button("Create File").on_press(Message::CreatFile),]
|
||||
.spacing(10)
|
||||
.width(200)
|
||||
.height(200)
|
||||
.align_x(Horizontal::Center),
|
||||
column![
|
||||
pick_list(
|
||||
app.all_saves.clone(),
|
||||
Some(&app.music.file_name),
|
||||
move |s| Message::FileNameChanged(s),
|
||||
),
|
||||
button("Load File").on_press(Message::Load),
|
||||
text("")
|
||||
]
|
||||
column![button("Load File").on_press(Message::Load),]
|
||||
.spacing(10)
|
||||
.width(200)
|
||||
.height(200)
|
||||
|
||||
108
src/main.rs
108
src/main.rs
@@ -1,6 +1,8 @@
|
||||
mod polygon_draw;
|
||||
use iced::keyboard::Modifiers;
|
||||
use pathdiff::diff_paths;
|
||||
use polygon_draw::Polygon;
|
||||
use std::path::PathBuf;
|
||||
|
||||
mod music;
|
||||
use music::Music;
|
||||
@@ -14,6 +16,7 @@ mod message;
|
||||
use message::Message;
|
||||
|
||||
mod utils;
|
||||
use rfd::FileDialog;
|
||||
use utils::{delta_to_string, is_delta_format_valid, str_to_sec};
|
||||
|
||||
use std::fs;
|
||||
@@ -24,15 +27,15 @@ use gui::{load_file_view, music_view};
|
||||
use iced::Font;
|
||||
use iced::Theme;
|
||||
use iced::{
|
||||
event::{self, Status},
|
||||
keyboard::{key::Named, Key},
|
||||
Color, Event, Task,
|
||||
event::{self, Status},
|
||||
keyboard::{Key, key::Named},
|
||||
};
|
||||
|
||||
use std::time::Instant;
|
||||
|
||||
use kira::{
|
||||
sound::static_sound::StaticSoundData, AudioManager, AudioManagerSettings, DefaultBackend,
|
||||
AudioManager, AudioManagerSettings, DefaultBackend, sound::static_sound::StaticSoundData,
|
||||
};
|
||||
const FONT_BYTES: &[u8] = include_bytes!("../fonts/EnvyCodeRNerdFontMono-Regular.ttf");
|
||||
const FONT: Font = Font::with_name("EnvyCodeR Nerd Font Mono");
|
||||
@@ -72,7 +75,6 @@ struct Polymusic {
|
||||
time_last_frame: Instant,
|
||||
paused: bool,
|
||||
audio_manager: AudioManager,
|
||||
all_sounds: Vec<String>,
|
||||
all_saves: Vec<String>,
|
||||
current_delta: f32,
|
||||
str_music_length: String,
|
||||
@@ -80,9 +82,9 @@ struct Polymusic {
|
||||
can_unpaused: bool,
|
||||
already_save: bool,
|
||||
mode_file_load: bool,
|
||||
file_name_to_creat: String,
|
||||
show_warning_message_creat: bool,
|
||||
historic: Historic,
|
||||
root: String,
|
||||
}
|
||||
|
||||
impl Polymusic {
|
||||
@@ -94,7 +96,6 @@ impl Polymusic {
|
||||
time_last_frame: Instant::now(),
|
||||
audio_manager: manager,
|
||||
paused: true,
|
||||
all_sounds: load_path_sounds(),
|
||||
all_saves: load_path_saves(),
|
||||
music: Music::default(),
|
||||
current_delta: 0.0,
|
||||
@@ -103,9 +104,9 @@ impl Polymusic {
|
||||
can_unpaused: true,
|
||||
already_save: true,
|
||||
mode_file_load: true,
|
||||
file_name_to_creat: "Default File Name".to_string(),
|
||||
show_warning_message_creat: false,
|
||||
historic: Historic::new(),
|
||||
root: String::from("/"),
|
||||
},
|
||||
Task::none(),
|
||||
)
|
||||
@@ -156,33 +157,69 @@ impl Polymusic {
|
||||
self.current_delta,
|
||||
);
|
||||
}
|
||||
|
||||
Message::ChangeSound(i, s) => {
|
||||
let sound = StaticSoundData::from_file(format!("./assets/{s}"))
|
||||
.expect("Fail to load audio");
|
||||
let old_sound = self
|
||||
.music
|
||||
Message::ReChangeSound(i, s) => {
|
||||
dbg!(format!("{0}/{1}", self.root, s.clone()));
|
||||
let sound = if s == String::from("Default_Sound.ogg") {
|
||||
StaticSoundData::from_file(String::from("./assets/Default_Sound.ogg"))
|
||||
.expect("Fail to load audio")
|
||||
} else {
|
||||
StaticSoundData::from_file(format!("{0}/{1}", self.root, s.clone()))
|
||||
.expect("Fail to load audio")
|
||||
};
|
||||
self.music
|
||||
.set_sound(self.current_delta, i, sound, s.clone());
|
||||
self.already_save = false;
|
||||
}
|
||||
|
||||
Message::ChangeSound(i) => {
|
||||
let file = FileDialog::new()
|
||||
.add_filter("Audio Files", &["mp3", "wav", "ogg"])
|
||||
.set_directory("./")
|
||||
.pick_file();
|
||||
if let Some(s) = file {
|
||||
let root_path = PathBuf::from(&self.root);
|
||||
let relative_path = diff_paths(&s, &root_path)
|
||||
.expect("Impossible de calculer le chemin relatif");
|
||||
let path_string = relative_path.to_string_lossy().into_owned();
|
||||
let sound = StaticSoundData::from_file(format!(
|
||||
"{0}/{1}",
|
||||
self.root,
|
||||
path_string.clone()
|
||||
))
|
||||
.expect("Fail to load audio");
|
||||
let old_sound =
|
||||
self.music
|
||||
.set_sound(self.current_delta, i, sound, path_string.clone());
|
||||
self.already_save = false;
|
||||
self.historic.add(
|
||||
Message::ChangeSound(i, old_sound),
|
||||
Message::ChangeSound(i, s),
|
||||
Message::ReChangeSound(i, old_sound),
|
||||
Message::ReChangeSound(i, path_string),
|
||||
self.current_delta,
|
||||
);
|
||||
}
|
||||
}
|
||||
Message::Save => {
|
||||
let json = serde_json::to_string_pretty(&self.music).unwrap();
|
||||
fs::write(format!("./saves/{0}.pmx", &self.music.file_name), json).unwrap();
|
||||
dbg!(format!("{0}/{1}", &self.root, self.music.file_name));
|
||||
fs::write(format!("{0}/{1}", &self.root, self.music.file_name), json).unwrap();
|
||||
self.all_saves = load_path_saves();
|
||||
self.already_save = true;
|
||||
}
|
||||
Message::Load => {
|
||||
let json = fs::read_to_string(format!("./saves/{0}.pmx", &self.music.file_name));
|
||||
let file = FileDialog::new()
|
||||
.add_filter("Polymusic File", &["pmx"])
|
||||
.set_directory("./")
|
||||
.pick_file();
|
||||
if let Some(path) = file {
|
||||
let path_string = path.to_string_lossy().into_owned();
|
||||
let json = fs::read_to_string(path_string.clone());
|
||||
if let Some(path_parent) = path.parent() {
|
||||
self.root = path_parent.to_string_lossy().into_owned();
|
||||
match json {
|
||||
Ok(j) => {
|
||||
let decoded: Music = serde_json::from_str(&j).unwrap();
|
||||
self.music = decoded;
|
||||
self.music.update_frame();
|
||||
self.music.update_frame(&self.root);
|
||||
self.mode_file_load = false;
|
||||
}
|
||||
Err(e) => {
|
||||
@@ -190,18 +227,26 @@ impl Polymusic {
|
||||
}
|
||||
}
|
||||
}
|
||||
Message::SetFileNameCreat(s) => self.file_name_to_creat = s,
|
||||
}
|
||||
}
|
||||
|
||||
Message::CreatFile => {
|
||||
if self.all_saves.contains(&self.file_name_to_creat) {
|
||||
self.show_warning_message_creat = true;
|
||||
} else {
|
||||
let file = FileDialog::new()
|
||||
.add_filter("Polymusic File", &["pmx"])
|
||||
.set_directory("./")
|
||||
.save_file();
|
||||
if let Some(path) = file {
|
||||
if let Some(path_parent) = path.parent() {
|
||||
self.root = path_parent.to_string_lossy().into_owned();
|
||||
}
|
||||
self.mode_file_load = false;
|
||||
self.music = Music::default();
|
||||
self.music.file_name = self.file_name_to_creat.clone();
|
||||
if let Some(name) = path.file_name() {
|
||||
self.music.file_name = name.to_string_lossy().into_owned();
|
||||
}
|
||||
self.update(Message::Save);
|
||||
}
|
||||
}
|
||||
Message::FileNameChanged(s) => self.music.file_name = s,
|
||||
Message::LengthChange(s) => {
|
||||
if is_delta_format_valid(&s) {
|
||||
let sec = str_to_sec(&s);
|
||||
@@ -345,7 +390,6 @@ impl Polymusic {
|
||||
if self.already_save {
|
||||
self.historic = Historic::new();
|
||||
self.paused = true;
|
||||
self.file_name_to_creat = "Default File Name".to_string();
|
||||
self.show_warning_message_creat = false;
|
||||
self.mode_file_load = true
|
||||
}
|
||||
@@ -373,11 +417,11 @@ impl Polymusic {
|
||||
}
|
||||
}
|
||||
|
||||
fn view(&self) -> iced::Element<Message> {
|
||||
fn view(&self) -> iced::Element<'_, Message> {
|
||||
if !self.mode_file_load {
|
||||
music_view(self)
|
||||
} else {
|
||||
load_file_view(self)
|
||||
load_file_view()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -452,16 +496,6 @@ impl Polymusic {
|
||||
}
|
||||
}
|
||||
|
||||
fn load_path_sounds() -> Vec<String> {
|
||||
let mut entries: Vec<String> = fs::read_dir("./assets")
|
||||
.unwrap()
|
||||
.filter_map(|res| res.ok())
|
||||
.map(|e| e.path().file_name().unwrap().to_str().unwrap().to_string())
|
||||
.collect();
|
||||
entries.sort();
|
||||
entries
|
||||
}
|
||||
|
||||
fn load_path_saves() -> Vec<String> {
|
||||
fs::create_dir_all("./saves").expect("fail to creat 'saves' !");
|
||||
let mut saves: Vec<String> = fs::read_dir("./saves")
|
||||
|
||||
@@ -6,13 +6,11 @@ use crate::polygon_draw::Polygon;
|
||||
pub enum Message {
|
||||
None,
|
||||
CreatFile,
|
||||
SetFileNameCreat(String),
|
||||
GoToLoadView,
|
||||
ForceToQuit,
|
||||
Tick,
|
||||
Save,
|
||||
Load,
|
||||
FileNameChanged(String),
|
||||
TogglePaused,
|
||||
ChangeDelta(f32),
|
||||
ClickedOnTimeLine(f32),
|
||||
@@ -23,7 +21,8 @@ pub enum Message {
|
||||
ReAddPolygon(Polygon),
|
||||
ChangeTeta(usize, f32),
|
||||
Remove(usize),
|
||||
ChangeSound(usize, String),
|
||||
ChangeSound(usize),
|
||||
ReChangeSound(usize, String),
|
||||
LengthChange(String),
|
||||
AddPoint,
|
||||
RemovePoint,
|
||||
|
||||
14
src/music.rs
14
src/music.rs
@@ -3,16 +3,16 @@ use crate::polygon_draw::*;
|
||||
use crate::utils::string_to_polygon;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use kira::{sound::static_sound::StaticSoundData, AudioManager};
|
||||
use kira::{AudioManager, sound::static_sound::StaticSoundData};
|
||||
|
||||
use iced::event::Status;
|
||||
use iced::mouse::Cursor;
|
||||
use iced::widget::canvas::{Event, Geometry};
|
||||
use iced::{keyboard, Vector};
|
||||
use iced::{
|
||||
mouse::{self, ScrollDelta},
|
||||
Size,
|
||||
mouse::{self, ScrollDelta},
|
||||
};
|
||||
use iced::{Vector, keyboard};
|
||||
|
||||
use iced::widget::canvas;
|
||||
use iced::widget::canvas::Stroke;
|
||||
@@ -83,9 +83,9 @@ impl Music {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update_frame(&mut self) {
|
||||
pub fn update_frame(&mut self, path_of_project: &str) {
|
||||
for (_, p) in &mut self.poly_frame {
|
||||
p.update();
|
||||
p.update(path_of_project);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -174,8 +174,8 @@ impl Music {
|
||||
|
||||
pub fn add_polygon(&mut self, delta: f32, polygon_name: String) {
|
||||
let current_frame = self.find_poly_frame(delta);
|
||||
let mut poly = string_to_polygon(polygon_name);
|
||||
poly.update();
|
||||
let poly = string_to_polygon(polygon_name);
|
||||
//poly.update();
|
||||
current_frame.polygons.push(poly);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
use crate::utils::string_to_color;
|
||||
|
||||
use crate::color::color_serde;
|
||||
use std::f32::consts::PI;
|
||||
|
||||
use iced::Size;
|
||||
use iced::Vector;
|
||||
use iced::mouse;
|
||||
use iced::widget::canvas;
|
||||
use iced::widget::canvas::{Frame, Stroke, Style};
|
||||
use iced::Size;
|
||||
use iced::Vector;
|
||||
use iced::{Color, Point, Rectangle, Renderer, Theme};
|
||||
use kira::sound::static_sound::StaticSoundData;
|
||||
use serde::{Deserialize, Serialize};
|
||||
@@ -38,9 +37,9 @@ impl PolygonFrame {
|
||||
}
|
||||
all_sound
|
||||
}
|
||||
pub fn update(&mut self) {
|
||||
pub fn update(&mut self, path_of_project: &str) {
|
||||
for poly in &mut self.polygons {
|
||||
poly.update();
|
||||
poly.update(path_of_project);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -199,9 +198,10 @@ pub struct Polygon {
|
||||
}
|
||||
#[warn(dead_code)]
|
||||
impl Polygon {
|
||||
pub fn update(&mut self) {
|
||||
let path = format!("./assets/{0}", &self.sound_name);
|
||||
self.sound = StaticSoundData::from_file(&path).expect("fail to load the sound");
|
||||
pub fn update(&mut self, path_of_project: &str) {
|
||||
let path = format!("{0}", &self.sound_name);
|
||||
self.sound = StaticSoundData::from_file(format!("{0}/{1}", path_of_project, path))
|
||||
.expect("fail to load the sound");
|
||||
}
|
||||
pub fn sound_to_play_btw(&self, before: f32, after: f32) -> Vec<&StaticSoundData> {
|
||||
let mut sound_to_play: Vec<&StaticSoundData> = vec![];
|
||||
@@ -224,7 +224,7 @@ impl Polygon {
|
||||
global_teta: 0.,
|
||||
points_teta: vec![],
|
||||
sound: sound,
|
||||
sound_name: "tick.ogg".to_string(),
|
||||
sound_name: "Default_Sound.ogg".to_string(),
|
||||
name: "".to_string(),
|
||||
color: Color::BLACK,
|
||||
show_color_picker: false,
|
||||
|
||||
13
src/utils.rs
13
src/utils.rs
@@ -1,5 +1,4 @@
|
||||
use crate::Polygon;
|
||||
use iced::Color;
|
||||
use kira::sound::static_sound::StaticSoundData;
|
||||
use regex::Regex;
|
||||
|
||||
@@ -7,16 +6,6 @@ pub fn is_delta_format_valid(str: &str) -> bool {
|
||||
let re = Regex::new(r"^\d{1,2}:\d{1,2}:\d{1,2}$").unwrap();
|
||||
re.is_match(str)
|
||||
}
|
||||
pub fn string_to_color<S: AsRef<str>>(s: S) -> Color {
|
||||
match s.as_ref() {
|
||||
"Green" => Color::from_rgb(0.0, 1.0, 0.0),
|
||||
"Blue" => Color::from_rgb(0.0, 0.0, 1.0),
|
||||
"Cyan" => Color::from_rgb(0.0, 1.0, 1.0),
|
||||
"Yellow" => Color::from_rgb(1.0, 1.0, 0.0),
|
||||
"Pink" => Color::from_rgb(1.0, 0.0, 1.0),
|
||||
_ => Color::BLACK,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn delta_to_string(delta: f32) -> String {
|
||||
let time = [
|
||||
@@ -95,5 +84,5 @@ pub fn string_to_polygon<S: AsRef<str>>(str: S) -> Polygon {
|
||||
poly
|
||||
}
|
||||
fn dummy_sound() -> StaticSoundData {
|
||||
StaticSoundData::from_file("assets/tick.ogg").expect("Fail to load audio")
|
||||
StaticSoundData::from_file("assets/Default_Sound.ogg").expect("Fail to load audio")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user