4 Commits

Author SHA1 Message Date
68f8cff151 padding 2025-07-09 11:21:02 +02:00
e85ed8371d timeline clickable 2025-07-09 11:18:15 +02:00
bf2266955b add remove point 2025-07-09 09:33:26 +02:00
4d31708481 change sounds 2025-07-09 01:35:16 +02:00
52 changed files with 102 additions and 29 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
assets/a-3.mp3 Normal file

Binary file not shown.

BIN
assets/a-4.mp3 Normal file

Binary file not shown.

BIN
assets/a-5.mp3 Normal file

Binary file not shown.

BIN
assets/a3.mp3 Normal file

Binary file not shown.

BIN
assets/a4.mp3 Normal file

Binary file not shown.

BIN
assets/a5.mp3 Normal file

Binary file not shown.

BIN
assets/b3.mp3 Normal file

Binary file not shown.

BIN
assets/b4.mp3 Normal file

Binary file not shown.

BIN
assets/b5.mp3 Normal file

Binary file not shown.

BIN
assets/c-3.mp3 Normal file

Binary file not shown.

BIN
assets/c-4.mp3 Normal file

Binary file not shown.

BIN
assets/c-5.mp3 Normal file

Binary file not shown.

BIN
assets/c3.mp3 Normal file

Binary file not shown.

BIN
assets/c4.mp3 Normal file

Binary file not shown.

BIN
assets/c5.mp3 Normal file

Binary file not shown.

BIN
assets/c6.mp3 Normal file

Binary file not shown.

BIN
assets/d-3.mp3 Normal file

Binary file not shown.

BIN
assets/d-4.mp3 Normal file

Binary file not shown.

BIN
assets/d-5.mp3 Normal file

Binary file not shown.

BIN
assets/d3.mp3 Normal file

Binary file not shown.

BIN
assets/d4.mp3 Normal file

Binary file not shown.

BIN
assets/d5.mp3 Normal file

Binary file not shown.

BIN
assets/e3.mp3 Normal file

Binary file not shown.

BIN
assets/e4.mp3 Normal file

Binary file not shown.

BIN
assets/e5.mp3 Normal file

Binary file not shown.

BIN
assets/f-3.mp3 Normal file

Binary file not shown.

BIN
assets/f-4.mp3 Normal file

Binary file not shown.

BIN
assets/f-5.mp3 Normal file

Binary file not shown.

BIN
assets/f3.mp3 Normal file

Binary file not shown.

BIN
assets/f4.mp3 Normal file

Binary file not shown.

BIN
assets/f5.mp3 Normal file

Binary file not shown.

BIN
assets/g-3.mp3 Normal file

Binary file not shown.

BIN
assets/g-4.mp3 Normal file

Binary file not shown.

BIN
assets/g-5.mp3 Normal file

Binary file not shown.

BIN
assets/g3.mp3 Normal file

Binary file not shown.

BIN
assets/g4.mp3 Normal file

Binary file not shown.

BIN
assets/g5.mp3 Normal file

Binary file not shown.

View File

@@ -1,9 +1,13 @@
mod polygon_draw;
use iced::widget::canvas::Program;
use polygon_draw::Polygon;
mod music;
use music::Music;
mod message;
use message::Message;
mod utils;
use utils::str_to_sec;
@@ -38,27 +42,6 @@ fn main() -> iced::Result {
.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 {
music: Music,
time_last_frame: Instant,
@@ -173,6 +156,12 @@ impl MyApp {
Message::AddPoint => {
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)
))
.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),
column![
/*
slider(0.0..=self.music.length, self.current_delta, move |f| {
Message::ChangeDelta(f)
})
.step(&self.music.length / 10_000.),
.step(&self.music.length / 10_000.),*/
canvas(&self.music)
.height(Length::FillPortion(1))
.width(Length::FillPortion(1))
]
.spacing(0),
]
.spacing(20)
.height(Length::FillPortion(1))
.width(Length::FillPortion(1)),
]

22
src/message.rs Normal file
View 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),
}

View File

@@ -1,10 +1,15 @@
use crate::message::Message;
use crate::utils::string_to_polygon;
use crate::{polygon_draw::*, utils::string_to_color};
use serde::{Deserialize, Serialize};
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::Stroke;
use iced::widget::canvas::Style;
@@ -35,6 +40,17 @@ impl Music {
&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~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
pub fn current_frame(&self, delta: f32) -> &PolygonFrame {
if let Some(i) = self
@@ -121,6 +137,12 @@ impl Music {
self.poly_frame
.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) {
let current_frame = self.find_poly_frame(delta);
@@ -132,13 +154,13 @@ impl Music {
self.find_poly_frame(delta).polygons.remove(i);
}
}
impl<Message> canvas::Program<Message> for Music {
impl canvas::Program<Message> for Music {
// No internal state
type State = ();
type State = bool;
fn draw(
&self,
_state: &(),
_state: &Self::State,
renderer: &Renderer,
_theme: &Theme,
bounds: Rectangle,
@@ -149,7 +171,7 @@ impl<Message> canvas::Program<Message> for Music {
let padding = 8.;
let w = bounds.width - (padding * 2.);
for (delta, _) in &self.poly_frame {
let x = delta / self.length * w + padding;
let x = delta / self.length * w + 8.;
frame.fill_rectangle(
iced::Point { x: x, y: 0.0 },
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(
iced::Point::new(x, 0.),
iced::Size {
@@ -187,4 +209,41 @@ impl<Message> canvas::Program<Message> for Music {
// Then, we produce the 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)
}
}