From: Huck Boles Date: Mon, 3 Jul 2023 02:28:52 +0000 (-0500) Subject: edited: ui tweaks X-Git-Url: https://git.huck.website/?a=commitdiff_plain;h=eefc938c3105648ea0f7e7488320554c94554fa5;p=cellseq.git edited: ui tweaks --- diff --git a/src/display.rs b/src/display.rs index 9aafdbe..eb9021b 100644 --- a/src/display.rs +++ b/src/display.rs @@ -17,14 +17,22 @@ pub struct ControlMessage { } pub fn top_controls<'a>(is_playing: bool) -> Element<'a, Message> { - let play_button = - button(if is_playing { "pause" } else { "play" }).on_press(Message::TogglePlayback); + let play_button = row![ + button(if is_playing { "stop" } else { "play" }).on_press(Message::TogglePlayback), + button("save") + .on_press(Message::Save) + .style(theme::Button::Positive), + button("clear") + .on_press(Message::Clear) + .style(theme::Button::Destructive), + ] + .width(Length::Fill) + .spacing(10); let other_controls = row![button("quit") .on_press(Message::Quit) .style(theme::Button::Destructive),] .width(Length::Fill) - .align_items(Alignment::End) .spacing(10); row![play_button, other_controls] @@ -35,91 +43,78 @@ pub fn top_controls<'a>(is_playing: bool) -> Element<'a, Message> { } pub fn bottom_controls<'a>(message: ControlMessage) -> Element<'a, Message> { - column![map_section(&message), midi_section(&message),] - .width(Length::Fill) - .height(Length::Fill) - .padding(10) - .spacing(20) - .align_items(Alignment::Center) - .into() + column![ + map_section(&message), + probability_section(message.info.probability).width(Length::Fixed(600.0)), + midi_section(&message), + ] + .width(Length::Fill) + .height(Length::Fill) + .padding(10) + .spacing(20) + .align_items(Alignment::Center) + .into() } fn map_section<'a>(message: &ControlMessage) -> Row<'a, Message> { row![ map_buttons(), - column![ - probability_section(message.info.probability), - randomize_section(message.randomness) - ] - .padding(10) - .spacing(10) - .align_items(Alignment::Center) + randomize_section(message.randomness).width(Length::Fixed(500.0)) ] .spacing(10) } fn probability_section<'a>(p: f32) -> Row<'a, Message> { row![ + text("probability a cell gets triggered") + .style(theme::Text::Color(iced::Color::from_rgb8(0x60, 0x60, 0x60))), slider(0.0..=100.0, p * 100.0, |x| { Message::ProbChanged(x / 100.0) }), text(format!("{p}")), - text("probability a cell gets triggered") - .style(theme::Text::Color(iced::Color::from_rgb8(0x40, 0x40, 0x40))) ] .spacing(10) } fn randomize_section<'a>(r: f32) -> Row<'a, Message> { row![ + text("percent of board to fill on randomize") + .style(theme::Text::Color(iced::Color::from_rgb8(0x60, 0x60, 0x60))), slider(0.0..=100.0, r * 100.0, |x| { Message::RandChanged(x / 100.0) }), text(format!("{r}")), - text("percent of board to fill on randomize") - .style(theme::Text::Color(iced::Color::from_rgb8(0x40, 0x40, 0x40))) ] .spacing(10) } fn map_buttons<'a>() -> Column<'a, Message> { - column![ - row![ - button("save") - .on_press(Message::Save) - .style(theme::Button::Positive), - button("clear") - .on_press(Message::Clear) - .style(theme::Button::Destructive), - ] - .spacing(10), - row![ - button("reset") - .on_press(Message::Reset) - .style(theme::Button::Secondary), - button("random") - .on_press(Message::Randomize) - .style(theme::Button::Primary), - ] - .spacing(10) + column![row![ + button("reset") + .on_press(Message::Reset) + .style(theme::Button::Secondary), + button("random") + .on_press(Message::Randomize) + .style(theme::Button::Primary), ] + .spacing(10)] .spacing(10) } fn velocity_sliders<'a>(min: u8, max: u8) -> Column<'a, Message> { column![ row![ - text(format!("{max}")), - slider(0..=127, max, Message::NewVMax), text("maximum velocity") - .style(theme::Text::Color(iced::Color::from_rgb8(0x40, 0x40, 0x40))) + .style(theme::Text::Color(iced::Color::from_rgb8(0x60, 0x60, 0x60))), + slider(0..=127, max, Message::NewVMax), + text(format!("{max}")), ] .spacing(10), row![ - text(format!("{min}")), - slider(0..=127, min, Message::NewVMin), text("minimum velocity") - .style(theme::Text::Color(iced::Color::from_rgb8(0x40, 0x40, 0x40))) + .style(theme::Text::Color(iced::Color::from_rgb8(0x60, 0x60, 0x60))), + slider(0..=127, min, Message::NewVMin), + text(format!("{min}")), ] .spacing(10), ] @@ -130,6 +125,7 @@ fn midi_section<'a>(message: &ControlMessage) -> Column<'a, Message> { column![ song_section(message), velocity_sliders(message.info.velocity.min(), message.info.velocity.max()) + .width(Length::Fixed(500.0)) ] .spacing(10) } @@ -230,11 +226,13 @@ fn scale_selector<'a>(scale: Scale, note: RootNote, acc: Accidental) -> Row<'a, row![ pick_list(&RootNote::ALL[..], Some(note), move |note| { Message::NewNote(Root::new(note, acc)) - }), + }) + .width(Length::Fixed(50.0)), pick_list(&Accidental::ALL[..], Some(acc), move |acc| { Message::NewNote(Root::new(note, acc)) - }), - pick_list(&Scale::ALL[..], Some(scale), Message::Scale), + }) + .width(Length::Fixed(90.0)), + pick_list(&Scale::ALL[..], Some(scale), Message::Scale).width(Length::Fixed(160.0)), ] .align_items(Alignment::Center) } diff --git a/src/lib.rs b/src/lib.rs index 61e9b16..345c09d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,7 +3,7 @@ use iced::{ theme::Theme, time, widget::{column, container, row}, - {Alignment, Application, Command, Element, Length, Point, Subscription}, + window, {Alignment, Application, Command, Element, Length, Point, Subscription}, }; use itertools::Itertools; @@ -80,7 +80,7 @@ impl Default for SongInfo { Self { is_playing: false, bpm: 120, - divisor: 1, + divisor: 4, is_looping: false, loop_len: 16, step_num: 0, @@ -150,7 +150,6 @@ impl Application for CellSeq { fn update(&mut self, message: Message) -> Command { match message { - Message::Quit => todo!(), // TODO: figure out how to cleanly quit Message::None => {} Message::MapMessage(message) => self.map.update(message), Message::MaskMessage(message) => self.mask.update(message), @@ -213,6 +212,7 @@ impl Application for CellSeq { Message::OctaveRange(r) => self.info.octave.set_range(r), Message::NewNote(r) => self.info.root = r, Message::Voices(v) => self.info.voices = v, + Message::Quit => return window::close(), } Command::none() @@ -221,7 +221,7 @@ impl Application for CellSeq { fn subscription(&self) -> Subscription { if self.song.is_playing { time::every(Duration::from_millis( - 60000 / (self.song.bpm * self.song.divisor) as u64, + 240000 / (self.song.bpm * self.song.divisor) as u64, )) .map(Message::Tick) } else { @@ -237,13 +237,12 @@ impl Application for CellSeq { self.mask.view().map(Message::MaskMessage) ] .align_items(Alignment::Center) - .width(Length::Fill) .spacing(40) - .padding(20); + .padding(40); let bottom = bottom_controls(self.control_message()); - let content = column![top, map, bottom]; + let content = column![top, map, bottom].width(Length::Fill); container(content) .width(Length::Fill) diff --git a/src/main.rs b/src/main.rs index 4156b58..63867d8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,9 +1,6 @@ use std::{io::Write, thread::JoinHandle}; -use alsa::{ - rawmidi::{Rawmidi, IO}, - Direction, -}; +use alsa::{rawmidi::Rawmidi, Direction}; use cellseq::*; use iced::{window, Application, Settings}; diff --git a/src/map.rs b/src/map.rs index 1bcf23e..7398984 100644 --- a/src/map.rs +++ b/src/map.rs @@ -14,7 +14,7 @@ use rand::random; use rustc_hash::FxHashMap; use std::fmt::Debug; -#[derive(Default, Debug)] +#[derive(Debug)] pub struct Map { seed: CellMap, cells: CellMap, @@ -22,6 +22,17 @@ pub struct Map { randomness: f32, } +impl Default for Map { + fn default() -> Self { + Self { + seed: CellMap::default(), + cells: CellMap::default(), + life_cache: Cache::default(), + randomness: 0.5, + } + } +} + #[derive(Debug, Clone)] pub enum Message { Populate(Cell), diff --git a/src/music.rs b/src/music.rs index dfa8e7a..6a89cdc 100644 --- a/src/music.rs +++ b/src/music.rs @@ -148,13 +148,13 @@ pub enum RootNote { impl Display for RootNote { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let str = match self { - RootNote::A => "A", - RootNote::B => "B", - RootNote::C => "C", - RootNote::D => "D", - RootNote::E => "E", - RootNote::F => "F", - RootNote::G => "G", + RootNote::A => "a", + RootNote::B => "b", + RootNote::C => "c", + RootNote::D => "d", + RootNote::E => "e", + RootNote::F => "f", + RootNote::G => "g", }; write!(f, "{str}") @@ -184,9 +184,9 @@ pub enum Accidental { impl Display for Accidental { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let str = match self { - Accidental::Natural => "♮", - Accidental::Sharp => "♯", - Accidental::Flat => "♭", + Accidental::Natural => "natural", + Accidental::Sharp => "sharp", + Accidental::Flat => "flat", }; write!(f, "{str}") }