use crate::gui::icon_button::IconButton; use crate::gui::icons::{Icon, IconSet}; use crate::track::Track; use iced::widget::{button, column, container, row, slider, text}; use iced::{Alignment, Background, Color, Element, Length, Theme}; #[derive(Debug, Clone, Copy)] pub enum Message { MuteToggled, SoloToggled, RecordArmToggled, VolumeChanged(f32), PanChanged(f32), Delete, Select, } pub fn view<'a>(track: &'a Track, icons: &'a IconSet, height: f32) -> Element<'a, Message> { let color_strip = container(text("").width(3).height(Length::Fill)) .height(Length::Fill) .style(move |_theme: &Theme| container::Style { background: Some(Background::Color(Color::from_rgb8( track.color.r, track.color.g, track.color.b, ))), ..container::Style::default() }); let track_name = text(&track.name).size(15).width(Length::Fill); let track_type_label = text(format!("{}", track.track_type)) .size(9) .color(Color::from_rgb8(0x77, 0x77, 0x77)); let (mute_u, mute_f) = icons.get(Icon::Mute); let (solo_u, solo_f) = icons.get(Icon::Solo); let (rec_u, rec_f) = icons.get(Icon::RecordArm); let mute_btn: Element<'a, Message> = IconButton::new(mute_u, mute_f, Message::MuteToggled) .size(28.0) .toggled(track.muted) .active_tint(Color::from_rgb8(0xCC, 0xA7, 0x00)) .hint("Mute") .into(); let solo_btn: Element<'a, Message> = IconButton::new(solo_u, solo_f, Message::SoloToggled) .size(28.0) .toggled(track.soloed) .active_tint(Color::from_rgb8(0x00, 0x7A, 0xFF)) .hint("Solo") .into(); let rec_btn: Element<'a, Message> = IconButton::new(rec_u, rec_f, Message::RecordArmToggled) .size(28.0) .toggled(track.record_armed) .active_tint(Color::from_rgb8(0xCC, 0x33, 0x33)) .hint("Record Arm") .into(); let controls = row![mute_btn, solo_btn, rec_btn].spacing(2); let volume_slider = slider(0.0..=1.0, track.volume, Message::VolumeChanged) .step(0.01) .width(Length::Fill); let pan_slider = slider(-1.0..=1.0, track.pan, Message::PanChanged) .step(0.01) .width(Length::Fill); let del_btn = button(text("x").size(9)) .on_press(Message::Delete) .padding([1, 4]) .style(|_theme: &Theme, _status| button::Style { background: Some(Background::Color(Color::TRANSPARENT)), text_color: Color::from_rgb8(0x66, 0x66, 0x66), ..button::Style::default() }); let info = column![ row![track_name, del_btn].align_y(Alignment::Center), row![track_type_label, controls] .spacing(6) .align_y(Alignment::Center), row![text("Vol").size(9), volume_slider] .spacing(4) .align_y(Alignment::Center), row![text("Pan").size(9), pan_slider] .spacing(4) .align_y(Alignment::Center), ] .spacing(4) .padding([6, 8]) .width(Length::Fill); let inner = row![color_strip, info]; let content = button(inner) .on_press(Message::Select) .width(Length::Fill) .style(|_theme: &Theme, _status: button::Status| button::Style { background: Some(Background::Color(Color::TRANSPARENT)), text_color: Color::from_rgb8(0xCC, 0xCC, 0xCC), ..button::Style::default() }); container(content) .style(move |theme: &Theme| { if track.selected { container::Style { border: iced::Border { color: theme.extended_palette().primary.strong.color, width: 2.0, radius: 2.0.into(), }, background: Some(Background::Color(Color::from_rgb8(0x22, 0x28, 0x30))), ..container::Style::default() } } else { container::Style { border: iced::Border { color: Color::from_rgb8(0x2A, 0x2C, 0x2E), width: 1.0, radius: 0.0.into(), }, ..container::Style::default() } } }) .width(Length::Fill) .height(height) .into() }