use crate::config::ProjectConfig; use crate::entry::Message; use cpal::traits::{DeviceTrait, HostTrait}; use iced::widget::{button, column, container, pick_list, row, slider, text, text_input}; use iced::{Alignment, Element}; use std::collections::BTreeSet; #[derive(Debug, Clone)] pub struct State { pub config: ProjectConfig, pub available_devices: BTreeSet, } impl Default for State { fn default() -> Self { let host = cpal::default_host(); let devices = host .output_devices() .ok() .into_iter() .flatten() .filter_map(|d| d.name().ok()) .collect(); Self { config: ProjectConfig { name: "New Project".to_string(), sample_rate: 48000, buffer_size: 512, audio_device: "Default".to_string(), audio_input_device: "Default".to_string(), tempo: 120.0, time_signature_numerator: 4, time_signature_denominator: 4, }, available_devices: devices, } } } pub fn view(state: &State) -> Element<'static, Message> { let config = &state.config; let sample_rates = vec![44100, 48000, 96000]; let buffer_sizes = vec![256, 512, 1024]; let available_devices: Vec = state.available_devices.iter().cloned().collect(); let controls = column![ row![ text("Project Name:").width(150), text_input("My Awesome Track", &config.name).on_input(Message::ProjectNameChanged) ] .spacing(10), row![ text("Sample Rate:").width(150), pick_list( sample_rates, Some(config.sample_rate), Message::SampleRateSelected ) ] .spacing(10), row![ text("Buffer Size:").width(150), pick_list( buffer_sizes, Some(config.buffer_size), Message::BufferSizeSelected ) ] .spacing(10), row![ text("Audio Device:").width(150), pick_list( available_devices, Some(config.audio_device.clone()), Message::AudioDeviceSelected ) ] .spacing(10), row![ text("Time Signature:").width(150), text_input("4", &config.time_signature_numerator.to_string()) .on_input(Message::TimeSignatureNumeratorChanged) .width(50), text("/").width(20).align_x(Alignment::Center), text_input("4", &config.time_signature_denominator.to_string()) .on_input(Message::TimeSignatureDenominatorChanged) .width(50), ] .spacing(10) .align_y(Alignment::Center), row![ text("Tempo (BPM):").width(150), slider(40.0..=240.0, config.tempo, Message::TempoChanged).step(0.1), text(format!("{:.1}", config.tempo)) ] .spacing(10), // --- New "Time Utility" button --- container(row![ button("Time Utility").on_press(Message::ViewTimeUtility) ]) .align_x(Alignment::End), ] .spacing(10); column![ text("Create New Project").size(30), controls, row![ button("Create Project").on_press(Message::CreateProject), button("Cancel").on_press(Message::ViewRecentProjects) ] .spacing(10) ] .spacing(20) .align_x(Alignment::Center) .into() }