]> git.huck.website - cellseq.git/commitdiff
fixed: gui alignment issues
authorHuck Boles <huck@huck.website>
Sat, 8 Jul 2023 22:32:20 +0000 (17:32 -0500)
committerHuck Boles <huck@huck.website>
Sat, 8 Jul 2023 22:32:20 +0000 (17:32 -0500)
src/display.rs
src/lib.rs

index 948400201f53cf951bc2328adf21372b86c5d610..8e50f6419798ebef9b804766a6bab74e87bc6bf1 100644 (file)
@@ -1,7 +1,9 @@
 use iced::{
+    alignment::{Horizontal, Vertical},
     theme,
     widget::{
-        button, checkbox, column, pick_list, row, slider, text, vertical_slider, Column, Row,
+        button, checkbox, column, container, horizontal_space, pick_list, row, slider, text,
+        vertical_slider, vertical_space,
     },
     Alignment, Element, Length,
 };
@@ -19,251 +21,266 @@ pub struct ControlMessage {
 }
 
 pub fn top_controls<'a>(is_playing: bool) -> Element<'a, Message> {
-    let play_button = row![
-        button(if is_playing { "stop" } else { "play" }).on_press(Message::TogglePlayback),
-        button("save map")
-            .on_press(Message::Save)
-            .style(theme::Button::Positive),
-        button("reset map")
-            .on_press(Message::Reset)
-            .style(theme::Button::Secondary),
-        button("clear map")
-            .on_press(Message::ClearMap)
-            .style(theme::Button::Destructive),
-        button("clear mask")
-            .on_press(Message::ClearMask)
-            .style(theme::Button::Destructive),
-    ]
-    .width(Length::Fill)
-    .spacing(10);
+    let play_button = container(
+        row![
+            button(if is_playing { "stop" } else { "play" }).on_press(Message::TogglePlayback),
+            button("save map")
+                .on_press(Message::Save)
+                .style(theme::Button::Positive),
+            button("reset map")
+                .on_press(Message::Reset)
+                .style(theme::Button::Secondary),
+            button("clear map")
+                .on_press(Message::ClearMap)
+                .style(theme::Button::Destructive),
+            button("clear mask")
+                .on_press(Message::ClearMask)
+                .style(theme::Button::Destructive),
+        ]
+        .spacing(10),
+    )
+    .align_x(Horizontal::Left);
 
-    let other_controls = row![button("quit")
-        .on_press(Message::Quit)
-        .style(theme::Button::Destructive),]
-    .width(Length::Fill)
-    .align_items(Alignment::End)
-    .spacing(10);
+    let other_controls = container(
+        button("quit")
+            .on_press(Message::Quit)
+            .style(theme::Button::Destructive),
+    )
+    .align_x(Horizontal::Right);
 
-    row![play_button, other_controls]
-        .width(Length::Fill)
+    container(row![play_button, horizontal_space(Length::Fill), other_controls].width(Length::Fill))
         .padding(10)
-        .spacing(40)
+        .align_y(Vertical::Top)
         .into()
 }
 
 pub fn bottom_controls<'a>(message: ControlMessage) -> Element<'a, Message> {
-    column![
-        map_section(&message),
-        probability_section(&message).width(Length::Fixed(600.0)),
-        scale_selector(&message),
-        music_controls(&message)
-    ]
-    .width(Length::Fill)
-    .height(Length::Fill)
-    .padding(10)
-    .spacing(20)
-    .align_items(Alignment::Center)
-    .into()
-}
-
-fn music_controls<'a>(message: &ControlMessage) -> Row<'a, Message> {
-    row![
-        song_section(message),
-        midi_section(message),
-        velocity_sliders(message)
-    ]
-    .height(Length::Fill)
-    .padding(10)
-    .spacing(40)
+    container(
+        column![
+            randomize_section(message.randomness),
+            vertical_space(40),
+            music_controls(message)
+        ]
+        .align_items(Alignment::Center)
+        .padding(10)
+        .spacing(20),
+    )
+    .align_x(Horizontal::Center)
     .into()
 }
 
-fn song_section<'a>(message: &ControlMessage) -> Row<'a, Message> {
-    row![song_params(), song_vals(message)]
-        .height(Length::Fill)
+fn music_controls<'a>(message: ControlMessage) -> Element<'a, Message> {
+    container(
+        row![
+            column![
+                scale_selector(message),
+                row![song_section(message), midi_section(message),]
+                    .padding(10)
+                    .spacing(40),
+            ]
+            .align_items(Alignment::Center),
+            velocity_sliders(message)
+        ]
         .padding(10)
-        .spacing(20)
-        .into()
+        .spacing(40),
+    )
+    .into()
 }
 
-fn midi_section<'a>(message: &ControlMessage) -> Row<'a, Message> {
-    row![midi_params(), midi_vals(message)]
-        .height(Length::Fill)
-        .padding(10)
-        .spacing(20)
-        .into()
+fn song_section<'a>(message: ControlMessage) -> Element<'a, Message> {
+    container(
+        row![song_params(), song_vals(message)]
+            .padding(10)
+            .spacing(10),
+    )
+    .into()
 }
 
-fn song_params<'a>() -> Column<'a, Message> {
-    column![
-        text("loop section"),
-        text("number of steps"),
-        text("bpm"),
-        text("note division"),
-    ]
-    .height(Length::Fill)
-    .padding(10)
-    .spacing(20)
+fn midi_section<'a>(message: ControlMessage) -> Element<'a, Message> {
+    container(
+        row![midi_params(), midi_vals(message)]
+            .padding(10)
+            .spacing(10),
+    )
     .into()
 }
 
-fn song_vals<'a>(message: &ControlMessage) -> Column<'a, Message> {
-    column![
-        checkbox("", message.song.is_looping, |_| { Message::ToggleLoop }),
-        row![
-            button("-").on_press(Message::LoopLength(message.song.loop_len.saturating_sub(1))),
-            text(if message.song.is_looping {
-                format!("{}/{}", message.song.step_num, message.song.loop_len)
-            } else {
-                format!("{}", message.song.loop_len)
-            }),
-            button("+").on_press(Message::LoopLength(message.song.loop_len.saturating_add(1))),
-        ],
-        row![
-            button("-").on_press(Message::SpeedChanged(message.song.bpm.saturating_sub(1))),
-            text(format!("{}", message.song.bpm)),
-            button("+").on_press(Message::SpeedChanged(message.song.bpm.saturating_add(1))),
-        ],
-        row![
-            button("-").on_press(Message::NewDivision(message.song.divisor.saturating_sub(1))),
-            text(format!("{}", message.song.divisor)),
-            button("+").on_press(Message::NewDivision(message.song.divisor.saturating_add(1))),
+fn song_params<'a>() -> Element<'a, Message> {
+    container(
+        column![
+            text("bpm"),
+            text("note division"),
+            text("number of steps"),
+            text("loop section"),
         ]
-    ]
-    .height(Length::Fill)
-    .padding(10)
-    .spacing(20)
+        .align_items(Alignment::End)
+        .padding(10)
+        .spacing(30),
+    )
     .into()
 }
 
-fn midi_params<'a>() -> Column<'a, Message> {
-    column![
-        text("center octave"),
-        text("octave range"),
-        text("number of voices"),
-        text("midi channel"),
-    ]
-    .height(Length::Fill)
-    .padding(10)
-    .spacing(20)
+fn song_vals<'a>(message: ControlMessage) -> Element<'a, Message> {
+    container(
+        column![
+            row![
+                button("-").on_press(Message::SpeedChanged(message.song.bpm.saturating_sub(1))),
+                text(format!("{}", message.song.bpm)),
+                button("+").on_press(Message::SpeedChanged(message.song.bpm.saturating_add(1))),
+            ]
+            .align_items(Alignment::Center)
+            .spacing(10),
+            row![
+                button("-").on_press(Message::NewDivision(message.song.divisor.saturating_sub(1))),
+                text(format!("{}", message.song.divisor)),
+                button("+").on_press(Message::NewDivision(message.song.divisor.saturating_add(1))),
+            ]
+            .align_items(Alignment::Center)
+            .spacing(10),
+            row![
+                button("-").on_press(Message::LoopLength(message.song.loop_len.saturating_sub(1))),
+                text(if message.song.is_looping {
+                    format!("{}/{}", message.song.step_num, message.song.loop_len)
+                } else {
+                    format!("{}", message.song.loop_len)
+                }),
+                button("+").on_press(Message::LoopLength(message.song.loop_len.saturating_add(1))),
+            ]
+            .align_items(Alignment::Center)
+            .spacing(10),
+            checkbox("", message.song.is_looping, |_| { Message::ToggleLoop }),
+        ]
+        .align_items(Alignment::Center)
+        .padding(10)
+        .spacing(20),
+    )
     .into()
 }
 
-fn midi_vals<'a>(message: &ControlMessage) -> Column<'a, Message> {
-    column![
-        row![
-            button("-").on_press(Message::NewOctave(
-                message.info.octave.center.saturating_sub(1)
-            )),
-            text(format!("{}", message.info.octave.center)),
-            button("+").on_press(Message::NewOctave(
-                message.info.octave.center.saturating_add(1)
-            )),
-        ],
-        row![
-            button("-").on_press(Message::OctaveRange(
-                message.info.octave.range.saturating_sub(1)
-            )),
-            text(format!("{}", message.info.octave.range)),
-            button("+").on_press(Message::OctaveRange(
-                message.info.octave.range.saturating_add(1)
-            )),
-        ],
-        row![
-            button("-").on_press(Message::Voices(message.info.voices.saturating_sub(1))),
-            text(format!("{}", message.info.voices)),
-            button("+").on_press(Message::Voices(message.info.voices.saturating_add(1))),
-        ],
-        row![
-            button("-").on_press(Message::ChannelChange(
-                message.info.channel.saturating_sub(1)
-            )),
-            text(format!("{}", message.info.channel)),
-            button("+").on_press(Message::ChannelChange(
-                message.info.channel.saturating_add(1)
-            )),
+fn midi_params<'a>() -> Element<'a, Message> {
+    container(
+        column![
+            text("center octave"),
+            text("octave range"),
+            text("number of voices"),
+            text("midi channel"),
         ]
-    ]
-    .height(Length::Fill)
-    .padding(10)
-    .spacing(20)
+        .align_items(Alignment::End)
+        .padding(10)
+        .spacing(30),
+    )
     .into()
 }
 
-fn map_section<'a>(message: &ControlMessage) -> Row<'a, Message> {
-    row![
-        map_buttons(),
-        randomize_section(message.randomness).width(Length::Fixed(500.0))
-    ]
-    .spacing(10)
-}
-
-fn probability_section<'a>(message: &ControlMessage) -> Row<'a, Message> {
-    row![
-        text("probability a cell triggers a note"),
-        slider(0.0..=100.0, message.info.probability * 100.0, |x| {
-            Message::ProbChanged(x / 100.0)
-        }),
-        text(format!("{}", message.info.probability)),
-    ]
-    .spacing(10)
-}
-
-fn randomize_section<'a>(r: f32) -> Row<'a, Message> {
-    row![
-        slider(0.0..=100.0, r * 100.0, |x| {
-            Message::RandChanged(x / 100.0)
-        }),
-        text(format!("{r}")),
-    ]
-    .spacing(10)
+fn midi_vals<'a>(message: ControlMessage) -> Element<'a, Message> {
+    container(
+        column![
+            row![
+                button("-").on_press(Message::NewOctave(
+                    message.info.octave.center.saturating_sub(1)
+                )),
+                text(format!("{}", message.info.octave.center)),
+                button("+").on_press(Message::NewOctave(
+                    message.info.octave.center.saturating_add(1)
+                )),
+            ]
+            .spacing(10),
+            row![
+                button("-").on_press(Message::OctaveRange(
+                    message.info.octave.range.saturating_sub(1)
+                )),
+                text(format!("{}", message.info.octave.range)),
+                button("+").on_press(Message::OctaveRange(
+                    message.info.octave.range.saturating_add(1)
+                )),
+            ]
+            .spacing(10),
+            row![
+                button("-").on_press(Message::Voices(message.info.voices.saturating_sub(1))),
+                text(format!("{}", message.info.voices)),
+                button("+").on_press(Message::Voices(message.info.voices.saturating_add(1))),
+            ]
+            .spacing(10),
+            row![
+                button("-").on_press(Message::ChannelChange(
+                    message.info.channel.saturating_sub(1)
+                )),
+                text(format!("{}", message.info.channel)),
+                button("+").on_press(Message::ChannelChange(
+                    message.info.channel.saturating_add(1)
+                )),
+            ]
+            .spacing(10)
+        ]
+        .align_items(Alignment::Center)
+        .padding(10)
+        .spacing(20),
+    )
+    .into()
 }
 
-fn map_buttons<'a>() -> Row<'a, Message> {
-    row![
-        button("randomize map")
-            .on_press(Message::RandomizeMap)
-            .style(theme::Button::Primary),
-        button("randomize mask")
-            .on_press(Message::RandomizeMask)
-            .style(theme::Button::Primary),
-    ]
-    .spacing(10)
+fn randomize_section<'a>(r: f32) -> Element<'a, Message> {
+    container(
+        row![
+            button("randomize map")
+                .on_press(Message::RandomizeMap)
+                .style(theme::Button::Primary),
+            slider(0.0..=100.0, r * 100.0, |x| {
+                Message::RandChanged(x / 100.0)
+            })
+            .width(Length::Fixed(300.0)),
+            text(format!("{r}")),
+            button("randomize mask")
+                .on_press(Message::RandomizeMask)
+                .style(theme::Button::Primary),
+        ]
+        .spacing(20),
+    )
+    .into()
 }
 
-fn velocity_sliders<'a>(message: &ControlMessage) -> Column<'a, Message> {
-    column![
-        text("velocity range"),
-        row![
-            column![
-                text(format!("{}", message.info.velocity.max())),
-                vertical_slider(0..=127, message.info.velocity.max(), Message::NewVMax),
-                text("max")
-            ],
-            column![
-                text(format!("{}", message.info.velocity.min())),
-                vertical_slider(0..=127, message.info.velocity.min(), Message::NewVMin),
-                text("min")
-            ],
+fn velocity_sliders<'a>(message: ControlMessage) -> Element<'a, Message> {
+    container(
+        column![
+            text("velocity range"),
+            row![
+                column![
+                    text(format!("{}", message.info.velocity.max())),
+                    vertical_slider(0..=127, message.info.velocity.max(), Message::NewVMax),
+                    text("max")
+                ],
+                column![
+                    text(format!("{}", message.info.velocity.min())),
+                    vertical_slider(0..=127, message.info.velocity.min(), Message::NewVMin),
+                    text("min")
+                ],
+            ]
+            .spacing(20.0)
         ]
-    ]
-    .spacing(10)
+        .height(Length::Fixed(300.0))
+        .spacing(10),
+    )
+    .into()
 }
 
-fn scale_selector<'a>(message: &ControlMessage) -> Row<'a, Message> {
+fn scale_selector<'a>(message: ControlMessage) -> Element<'a, Message> {
     let scale = message.info.scale;
     let note = message.info.root.note;
     let accidental = message.info.root.accidental;
-    row![
-        pick_list(&RootNote::ALL[..], Some(note), move |note| {
-            Message::NewNote(Root { note, accidental })
-        })
-        .width(Length::Fixed(50.0)),
-        pick_list(&Accidental::ALL[..], Some(accidental), move |accidental| {
-            Message::NewNote(Root { note, accidental })
-        })
-        .width(Length::Fixed(90.0)),
-        pick_list(&Scale::ALL[..], Some(scale), Message::Scale).width(Length::Fixed(160.0)),
-    ]
-    .align_items(Alignment::Center)
+    container(
+        row![
+            pick_list(&RootNote::ALL[..], Some(note), move |note| {
+                Message::NewNote(Root { note, accidental })
+            })
+            .width(Length::Fixed(50.0)),
+            pick_list(&Accidental::ALL[..], Some(accidental), move |accidental| {
+                Message::NewNote(Root { note, accidental })
+            })
+            .width(Length::Fixed(90.0)),
+            pick_list(&Scale::ALL[..], Some(scale), Message::Scale).width(Length::Fixed(160.0)),
+        ]
+        .spacing(10),
+    )
+    .align_x(Horizontal::Center)
+    .into()
 }
index ba7430f7ed0e9d082fe7552ee416c23acf47dd6c..af6b704d24d0f3f5a00618c5ca62215483d5fe05 100644 (file)
@@ -1,9 +1,10 @@
 use iced::{
+    alignment::{Horizontal, Vertical},
     executor,
     theme::Theme,
     time,
-    widget::{column, container, row},
-    window, {Alignment, Application, Command, Element, Length, Point, Subscription},
+    widget::{column, container, row, text, vertical_slider, vertical_space},
+    window, Alignment, {Application, Command, Element, Length, Point, Subscription},
 };
 
 use itertools::Itertools;
@@ -162,7 +163,7 @@ impl Application for CellSeq {
                 return Command::perform(async move { hits }, Message::HitCount);
             }
             Message::Tick(_) => {
-                let map = if self.song.is_looping && self.song.step_num > self.song.loop_len {
+                let map = if self.song.is_looping && self.song.step_num >= self.song.loop_len {
                     self.song.step_num = 0;
                     self.map.reset_loop()
                 } else {
@@ -242,23 +243,41 @@ impl Application for CellSeq {
     fn view(&self) -> Element<Message> {
         let top = top_controls(self.song.is_playing);
 
-        let map = row![
-            self.map.view().map(Message::MapMessage),
-            self.mask.view().map(Message::MaskMessage)
-        ]
-        .width(Length::Fill)
-        .height(Length::Fill)
-        .align_items(Alignment::Center)
-        .spacing(40);
+        let probability_slider = container(
+            column![
+                text(format!("{}", self.info.probability)),
+                vertical_slider(0.0..=100.0, self.info.probability * 100.0, |x| {
+                    Message::ProbChanged(x / 100.0)
+                }),
+                text("note density")
+            ]
+            .height(Length::Fixed(350.0))
+            .align_items(Alignment::Center),
+        )
+        .align_y(Vertical::Top);
+
+        let map = container(
+            row![
+                self.map.view().map(Message::MapMessage),
+                probability_slider,
+                self.mask.view().map(Message::MaskMessage)
+            ]
+            .padding(10)
+            .spacing(20),
+        )
+        .align_x(Horizontal::Center);
 
         let bottom = bottom_controls(self.control_message());
 
-        let content = column![top, map, bottom].width(Length::Fill);
-
-        container(content)
-            .width(Length::Fill)
-            .height(Length::Fill)
-            .into()
+        container(
+            column![top, vertical_space(40), map, bottom]
+                .width(Length::Fill)
+                .align_items(Alignment::Center),
+        )
+        .align_x(Horizontal::Center)
+        .width(Length::Fill)
+        .height(Length::Fill)
+        .into()
     }
 
     fn theme(&self) -> Theme {