119 lines
3.6 KiB
Rust
119 lines
3.6 KiB
Rust
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<String>,
|
|
}
|
|
|
|
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<String> = 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()
|
|
} |