timeline clickable

This commit is contained in:
2025-07-09 11:18:15 +02:00
parent bf2266955b
commit e85ed8371d
3 changed files with 79 additions and 29 deletions

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,28 +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,
RemovePoint,
}
struct MyApp { struct MyApp {
music: Music, music: Music,
time_last_frame: Instant, time_last_frame: Instant,
@@ -177,6 +159,9 @@ impl MyApp {
Message::RemovePoint => { Message::RemovePoint => {
self.music.remove_point(self.current_delta); self.music.remove_point(self.current_delta);
} }
Message::ClickedOnTimeLine(f) => {
self.update(Message::ChangeDelta(f));
}
} }
} }
@@ -324,10 +309,11 @@ impl MyApp {
] ]
.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))

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;
@@ -149,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,
@@ -166,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(),
@@ -187,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 {
@@ -204,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)
}
} }