Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 68f8cff151 | |||
| e85ed8371d | |||
| bf2266955b | |||
| 4d31708481 |
Binary file not shown.
BIN
assets/A_LA.mp3
BIN
assets/A_LA.mp3
Binary file not shown.
BIN
assets/B_SI.mp3
BIN
assets/B_SI.mp3
Binary file not shown.
Binary file not shown.
BIN
assets/C_DO.mp3
BIN
assets/C_DO.mp3
Binary file not shown.
Binary file not shown.
BIN
assets/D_RE.mp3
BIN
assets/D_RE.mp3
Binary file not shown.
BIN
assets/E_MI.mp3
BIN
assets/E_MI.mp3
Binary file not shown.
Binary file not shown.
BIN
assets/F_FA.mp3
BIN
assets/F_FA.mp3
Binary file not shown.
Binary file not shown.
BIN
assets/G_SOL.mp3
BIN
assets/G_SOL.mp3
Binary file not shown.
BIN
assets/a-3.mp3
Normal file
BIN
assets/a-3.mp3
Normal file
Binary file not shown.
BIN
assets/a-4.mp3
Normal file
BIN
assets/a-4.mp3
Normal file
Binary file not shown.
BIN
assets/a-5.mp3
Normal file
BIN
assets/a-5.mp3
Normal file
Binary file not shown.
BIN
assets/a3.mp3
Normal file
BIN
assets/a3.mp3
Normal file
Binary file not shown.
BIN
assets/a4.mp3
Normal file
BIN
assets/a4.mp3
Normal file
Binary file not shown.
BIN
assets/a5.mp3
Normal file
BIN
assets/a5.mp3
Normal file
Binary file not shown.
BIN
assets/b3.mp3
Normal file
BIN
assets/b3.mp3
Normal file
Binary file not shown.
BIN
assets/b4.mp3
Normal file
BIN
assets/b4.mp3
Normal file
Binary file not shown.
BIN
assets/b5.mp3
Normal file
BIN
assets/b5.mp3
Normal file
Binary file not shown.
BIN
assets/c-3.mp3
Normal file
BIN
assets/c-3.mp3
Normal file
Binary file not shown.
BIN
assets/c-4.mp3
Normal file
BIN
assets/c-4.mp3
Normal file
Binary file not shown.
BIN
assets/c-5.mp3
Normal file
BIN
assets/c-5.mp3
Normal file
Binary file not shown.
BIN
assets/c3.mp3
Normal file
BIN
assets/c3.mp3
Normal file
Binary file not shown.
BIN
assets/c4.mp3
Normal file
BIN
assets/c4.mp3
Normal file
Binary file not shown.
BIN
assets/c5.mp3
Normal file
BIN
assets/c5.mp3
Normal file
Binary file not shown.
BIN
assets/c6.mp3
Normal file
BIN
assets/c6.mp3
Normal file
Binary file not shown.
BIN
assets/d-3.mp3
Normal file
BIN
assets/d-3.mp3
Normal file
Binary file not shown.
BIN
assets/d-4.mp3
Normal file
BIN
assets/d-4.mp3
Normal file
Binary file not shown.
BIN
assets/d-5.mp3
Normal file
BIN
assets/d-5.mp3
Normal file
Binary file not shown.
BIN
assets/d3.mp3
Normal file
BIN
assets/d3.mp3
Normal file
Binary file not shown.
BIN
assets/d4.mp3
Normal file
BIN
assets/d4.mp3
Normal file
Binary file not shown.
BIN
assets/d5.mp3
Normal file
BIN
assets/d5.mp3
Normal file
Binary file not shown.
BIN
assets/e3.mp3
Normal file
BIN
assets/e3.mp3
Normal file
Binary file not shown.
BIN
assets/e4.mp3
Normal file
BIN
assets/e4.mp3
Normal file
Binary file not shown.
BIN
assets/e5.mp3
Normal file
BIN
assets/e5.mp3
Normal file
Binary file not shown.
BIN
assets/f-3.mp3
Normal file
BIN
assets/f-3.mp3
Normal file
Binary file not shown.
BIN
assets/f-4.mp3
Normal file
BIN
assets/f-4.mp3
Normal file
Binary file not shown.
BIN
assets/f-5.mp3
Normal file
BIN
assets/f-5.mp3
Normal file
Binary file not shown.
BIN
assets/f3.mp3
Normal file
BIN
assets/f3.mp3
Normal file
Binary file not shown.
BIN
assets/f4.mp3
Normal file
BIN
assets/f4.mp3
Normal file
Binary file not shown.
BIN
assets/f5.mp3
Normal file
BIN
assets/f5.mp3
Normal file
Binary file not shown.
BIN
assets/g-3.mp3
Normal file
BIN
assets/g-3.mp3
Normal file
Binary file not shown.
BIN
assets/g-4.mp3
Normal file
BIN
assets/g-4.mp3
Normal file
Binary file not shown.
BIN
assets/g-5.mp3
Normal file
BIN
assets/g-5.mp3
Normal file
Binary file not shown.
BIN
assets/g3.mp3
Normal file
BIN
assets/g3.mp3
Normal file
Binary file not shown.
BIN
assets/g4.mp3
Normal file
BIN
assets/g4.mp3
Normal file
Binary file not shown.
BIN
assets/g5.mp3
Normal file
BIN
assets/g5.mp3
Normal file
Binary file not shown.
38
src/main.rs
38
src/main.rs
@@ -1,9 +1,13 @@
|
|||||||
mod polygon_draw;
|
mod polygon_draw;
|
||||||
|
use iced::widget::canvas::Program;
|
||||||
use polygon_draw::Polygon;
|
use polygon_draw::Polygon;
|
||||||
|
|
||||||
mod music;
|
mod music;
|
||||||
use music::Music;
|
use music::Music;
|
||||||
|
|
||||||
|
mod message;
|
||||||
|
use message::Message;
|
||||||
|
|
||||||
mod utils;
|
mod utils;
|
||||||
use utils::str_to_sec;
|
use utils::str_to_sec;
|
||||||
|
|
||||||
@@ -38,27 +42,6 @@ fn main() -> iced::Result {
|
|||||||
.run_with(MyApp::new)
|
.run_with(MyApp::new)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
enum Message {
|
|
||||||
ButtonPressedIncrement,
|
|
||||||
ButtonPressedDecrement,
|
|
||||||
Tick,
|
|
||||||
AddPolygon(String),
|
|
||||||
ChangeTeta(usize, f32),
|
|
||||||
Remove(usize),
|
|
||||||
ChangeColor(usize, String),
|
|
||||||
ChangeSound(usize, String),
|
|
||||||
ToggleSavePanel,
|
|
||||||
Save,
|
|
||||||
Load,
|
|
||||||
FileNameChanged(String),
|
|
||||||
TogglePaused,
|
|
||||||
SetMusicLength,
|
|
||||||
LengthChange(String),
|
|
||||||
ChangeDelta(f32),
|
|
||||||
AddPoint,
|
|
||||||
}
|
|
||||||
|
|
||||||
struct MyApp {
|
struct MyApp {
|
||||||
music: Music,
|
music: Music,
|
||||||
time_last_frame: Instant,
|
time_last_frame: Instant,
|
||||||
@@ -173,6 +156,12 @@ impl MyApp {
|
|||||||
Message::AddPoint => {
|
Message::AddPoint => {
|
||||||
self.music.add_point(self.current_delta);
|
self.music.add_point(self.current_delta);
|
||||||
}
|
}
|
||||||
|
Message::RemovePoint => {
|
||||||
|
self.music.remove_point(self.current_delta);
|
||||||
|
}
|
||||||
|
Message::ClickedOnTimeLine(f) => {
|
||||||
|
self.update(Message::ChangeDelta(f));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -315,20 +304,23 @@ impl MyApp {
|
|||||||
delta_to_string(self.music.length)
|
delta_to_string(self.music.length)
|
||||||
))
|
))
|
||||||
.size(20.0),
|
.size(20.0),
|
||||||
button("Add Point").on_press(Message::AddPoint)
|
button("Add Point").on_press(Message::AddPoint),
|
||||||
|
button("Remove Point").on_press(Message::RemovePoint),
|
||||||
]
|
]
|
||||||
.spacing(20),
|
.spacing(20),
|
||||||
column![
|
column![
|
||||||
|
/*
|
||||||
slider(0.0..=self.music.length, self.current_delta, move |f| {
|
slider(0.0..=self.music.length, self.current_delta, move |f| {
|
||||||
Message::ChangeDelta(f)
|
Message::ChangeDelta(f)
|
||||||
})
|
})
|
||||||
.step(&self.music.length / 10_000.),
|
.step(&self.music.length / 10_000.),*/
|
||||||
canvas(&self.music)
|
canvas(&self.music)
|
||||||
.height(Length::FillPortion(1))
|
.height(Length::FillPortion(1))
|
||||||
.width(Length::FillPortion(1))
|
.width(Length::FillPortion(1))
|
||||||
]
|
]
|
||||||
.spacing(0),
|
.spacing(0),
|
||||||
]
|
]
|
||||||
|
.spacing(20)
|
||||||
.height(Length::FillPortion(1))
|
.height(Length::FillPortion(1))
|
||||||
.width(Length::FillPortion(1)),
|
.width(Length::FillPortion(1)),
|
||||||
]
|
]
|
||||||
|
|||||||
22
src/message.rs
Normal file
22
src/message.rs
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub enum Message {
|
||||||
|
ButtonPressedIncrement,
|
||||||
|
ButtonPressedDecrement,
|
||||||
|
Tick,
|
||||||
|
AddPolygon(String),
|
||||||
|
ChangeTeta(usize, f32),
|
||||||
|
Remove(usize),
|
||||||
|
ChangeColor(usize, String),
|
||||||
|
ChangeSound(usize, String),
|
||||||
|
ToggleSavePanel,
|
||||||
|
Save,
|
||||||
|
Load,
|
||||||
|
FileNameChanged(String),
|
||||||
|
TogglePaused,
|
||||||
|
SetMusicLength,
|
||||||
|
LengthChange(String),
|
||||||
|
ChangeDelta(f32),
|
||||||
|
AddPoint,
|
||||||
|
RemovePoint,
|
||||||
|
ClickedOnTimeLine(f32),
|
||||||
|
}
|
||||||
71
src/music.rs
71
src/music.rs
@@ -1,10 +1,15 @@
|
|||||||
|
use crate::message::Message;
|
||||||
use crate::utils::string_to_polygon;
|
use crate::utils::string_to_polygon;
|
||||||
use crate::{polygon_draw::*, utils::string_to_color};
|
use crate::{polygon_draw::*, utils::string_to_color};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use kira::{AudioManager, sound::static_sound::StaticSoundData};
|
use kira::{AudioManager, sound::static_sound::StaticSoundData};
|
||||||
|
|
||||||
use iced::mouse;
|
use iced::event::Status;
|
||||||
|
use iced::mouse::Cursor;
|
||||||
|
use iced::widget::canvas::Event;
|
||||||
|
use iced::{mouse, padding};
|
||||||
|
|
||||||
use iced::widget::canvas;
|
use iced::widget::canvas;
|
||||||
use iced::widget::canvas::Stroke;
|
use iced::widget::canvas::Stroke;
|
||||||
use iced::widget::canvas::Style;
|
use iced::widget::canvas::Style;
|
||||||
@@ -35,6 +40,17 @@ impl Music {
|
|||||||
&mut self.poly_frame.last_mut().unwrap().1
|
&mut self.poly_frame.last_mut().unwrap().1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fn find_index_frame(&mut self, delta: f32) -> usize {
|
||||||
|
if let Some(i) = self
|
||||||
|
.poly_frame
|
||||||
|
.windows(2)
|
||||||
|
.position(|w| w[0].0 <= delta && delta < w[1].0)
|
||||||
|
{
|
||||||
|
i
|
||||||
|
} else {
|
||||||
|
self.poly_frame.len() - 1
|
||||||
|
}
|
||||||
|
}
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~PUBLIC~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~PUBLIC~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
pub fn current_frame(&self, delta: f32) -> &PolygonFrame {
|
pub fn current_frame(&self, delta: f32) -> &PolygonFrame {
|
||||||
if let Some(i) = self
|
if let Some(i) = self
|
||||||
@@ -121,6 +137,12 @@ impl Music {
|
|||||||
self.poly_frame
|
self.poly_frame
|
||||||
.insert(pos, (delta, self.current_frame(delta).clone()));
|
.insert(pos, (delta, self.current_frame(delta).clone()));
|
||||||
}
|
}
|
||||||
|
pub fn remove_point(&mut self, delta: f32) {
|
||||||
|
let i = self.find_index_frame(delta);
|
||||||
|
if i != 0 {
|
||||||
|
self.poly_frame.remove(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn add_polygon(&mut self, delta: f32, polygon_name: String) {
|
pub fn add_polygon(&mut self, delta: f32, polygon_name: String) {
|
||||||
let current_frame = self.find_poly_frame(delta);
|
let current_frame = self.find_poly_frame(delta);
|
||||||
@@ -132,13 +154,13 @@ impl Music {
|
|||||||
self.find_poly_frame(delta).polygons.remove(i);
|
self.find_poly_frame(delta).polygons.remove(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<Message> canvas::Program<Message> for Music {
|
impl canvas::Program<Message> for Music {
|
||||||
// No internal state
|
// No internal state
|
||||||
type State = ();
|
type State = bool;
|
||||||
|
|
||||||
fn draw(
|
fn draw(
|
||||||
&self,
|
&self,
|
||||||
_state: &(),
|
_state: &Self::State,
|
||||||
renderer: &Renderer,
|
renderer: &Renderer,
|
||||||
_theme: &Theme,
|
_theme: &Theme,
|
||||||
bounds: Rectangle,
|
bounds: Rectangle,
|
||||||
@@ -149,7 +171,7 @@ impl<Message> canvas::Program<Message> for Music {
|
|||||||
let padding = 8.;
|
let padding = 8.;
|
||||||
let w = bounds.width - (padding * 2.);
|
let w = bounds.width - (padding * 2.);
|
||||||
for (delta, _) in &self.poly_frame {
|
for (delta, _) in &self.poly_frame {
|
||||||
let x = delta / self.length * w + padding;
|
let x = delta / self.length * w + 8.;
|
||||||
frame.fill_rectangle(
|
frame.fill_rectangle(
|
||||||
iced::Point { x: x, y: 0.0 },
|
iced::Point { x: x, y: 0.0 },
|
||||||
frame.size(),
|
frame.size(),
|
||||||
@@ -170,7 +192,7 @@ impl<Message> canvas::Program<Message> for Music {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
let x = self.current_delta / self.length * w + padding;
|
let x = self.current_delta / self.length * w + 8.;
|
||||||
frame.stroke_rectangle(
|
frame.stroke_rectangle(
|
||||||
iced::Point::new(x, 0.),
|
iced::Point::new(x, 0.),
|
||||||
iced::Size {
|
iced::Size {
|
||||||
@@ -187,4 +209,41 @@ impl<Message> canvas::Program<Message> for Music {
|
|||||||
// Then, we produce the geometry
|
// Then, we produce the geometry
|
||||||
vec![frame.into_geometry()]
|
vec![frame.into_geometry()]
|
||||||
}
|
}
|
||||||
|
fn update(
|
||||||
|
&self,
|
||||||
|
state: &mut Self::State,
|
||||||
|
event: Event,
|
||||||
|
bounds: Rectangle,
|
||||||
|
cursor: Cursor,
|
||||||
|
) -> (Status, Option<Message>) {
|
||||||
|
//eprintln!("event = {:?}", event);
|
||||||
|
if let Event::Mouse(mouse_event) = event {
|
||||||
|
match mouse_event {
|
||||||
|
mouse::Event::ButtonPressed(mouse::Button::Left) => {
|
||||||
|
*state = true;
|
||||||
|
if let Some(position) = cursor.position_in(bounds) {
|
||||||
|
let pos_x = (position.x - 8.0) / (bounds.width - 16.);
|
||||||
|
let delta = (pos_x * self.length).clamp(0., self.length);
|
||||||
|
return (
|
||||||
|
Status::Captured,
|
||||||
|
Some(crate::message::Message::ClickedOnTimeLine(delta)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mouse::Event::ButtonReleased(mouse::Button::Left) => *state = false,
|
||||||
|
mouse::Event::CursorMoved { position: _ } => {
|
||||||
|
if let Some(position) = cursor.position_in(bounds)
|
||||||
|
&& *state
|
||||||
|
{
|
||||||
|
let pos_x = (position.x - 8.0) / (bounds.width - 16.);
|
||||||
|
let delta = (pos_x * self.length).clamp(0., self.length);
|
||||||
|
return (Status::Captured, Some(Message::ClickedOnTimeLine(delta)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
(Status::Ignored, None)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user