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; 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
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::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)
}
} }