From 68bf8086354ead06cc014236ca4fee606319b0c5 Mon Sep 17 00:00:00 2001 From: Alexander Heldt Date: Fri, 26 Dec 2025 12:13:11 +0100 Subject: [PATCH] Move styling to `style` and add `Border` type --- src/musicplayer/ui/layout.gleam | 12 +----- .../ui/layout_examples/layout_examples.gleam | 23 ++++++++--- src/musicplayer/ui/style.gleam | 34 +++++++++++++++ src/musicplayer/ui/ui.gleam | 41 ++++++++++--------- test/musicplayer/ui/layout_test.gleam | 23 ++++++++--- 5 files changed, 93 insertions(+), 40 deletions(-) create mode 100644 src/musicplayer/ui/style.gleam diff --git a/src/musicplayer/ui/layout.gleam b/src/musicplayer/ui/layout.gleam index c09496e..9099d7a 100644 --- a/src/musicplayer/ui/layout.gleam +++ b/src/musicplayer/ui/layout.gleam @@ -8,6 +8,7 @@ import gleam/string import musicplayer/ui/internal import musicplayer/ui/plot.{type Buffer} +import musicplayer/ui/style.{type Style, Percent, Style} pub const root_section = "reserved_root_section" @@ -19,15 +20,6 @@ pub type Section { PlaybackTime } -pub type Dimension { - Percent(width: Int, height: Int) - // TODO add Flex that flows -} - -pub type Style { - Style(dimensions: Dimension) -} - pub type Node { Row(heading: Option(String), style: Style, children: List(Section)) Cell(heading: Option(String), style: Style) @@ -88,7 +80,7 @@ fn view_loop(i: ViewIdx, view_nodes: List(#(Section, Node))) -> View { view_index_section(i), Row( heading: None, - style: Style(dimensions: Percent(width: 100, height: 100)), + style: Style(dimensions: Percent(width: 100, height: 100), border: None), children: orphans, ), ) diff --git a/src/musicplayer/ui/layout_examples/layout_examples.gleam b/src/musicplayer/ui/layout_examples/layout_examples.gleam index 1cbc8ed..0215e7e 100644 --- a/src/musicplayer/ui/layout_examples/layout_examples.gleam +++ b/src/musicplayer/ui/layout_examples/layout_examples.gleam @@ -1,8 +1,9 @@ import gleam/option.{Some} import musicplayer/ui/internal -import musicplayer/ui/layout.{Percent, Section, Style} +import musicplayer/ui/layout.{Section} import musicplayer/ui/layout_examples/wait_for_input.{wait_for_input} +import musicplayer/ui/style.{Percent, Style} pub fn main() { let assert Ok(columns) = internal.io_get_columns() @@ -24,7 +25,10 @@ fn two_rows_with_cells(columns: Int, rows: Int) -> layout.Layout { Section("Row1"), layout.Row( heading: Some("row 1"), - style: Style(dimensions: Percent(width: 100, height: 50)), + style: Style( + dimensions: Percent(width: 100, height: 50), + border: Some(style.BorderSingle), + ), children: [ Section("A"), Section("B"), @@ -35,21 +39,30 @@ fn two_rows_with_cells(columns: Int, rows: Int) -> layout.Layout { Section("A"), layout.Cell( heading: Some("cell 1"), - style: Style(dimensions: Percent(width: 50, height: 50)), + style: Style( + dimensions: Percent(width: 50, height: 50), + border: Some(style.BorderSingle), + ), ), ), #( Section("B"), layout.Cell( heading: Some("cell 2"), - style: Style(dimensions: Percent(width: 50, height: 50)), + style: Style( + dimensions: Percent(width: 50, height: 50), + border: Some(style.BorderSingle), + ), ), ), #( Section("Row2"), layout.Row( heading: Some("row 2"), - style: Style(dimensions: Percent(width: 50, height: 50)), + style: Style( + dimensions: Percent(width: 50, height: 50), + border: Some(style.BorderSingle), + ), children: [], ), ), diff --git a/src/musicplayer/ui/style.gleam b/src/musicplayer/ui/style.gleam new file mode 100644 index 0000000..ab07707 --- /dev/null +++ b/src/musicplayer/ui/style.gleam @@ -0,0 +1,34 @@ +import gleam/option.{type Option} + +pub type Dimension { + Percent(width: Int, height: Int) + // TODO add Flex that flows +} + +pub type Border { + BorderNone + BorderSingle +} + +pub type Style { + Style(dimensions: Dimension, border: Option(Border)) +} + +pub type BorderChars { + BorderChars( + top_left: String, + top_right: String, + bottom_left: String, + bottom_right: String, + horisontal: String, + vertical: String, + ) +} + +// https://en.wikipedia.org/wiki/Box-drawing_characters +pub fn border_chars(border: Border) -> BorderChars { + case border { + BorderNone -> BorderChars("", "", "", "", "", "") + BorderSingle -> BorderChars("┌", "┐", "└", "┘", "─", "│") + } +} diff --git a/src/musicplayer/ui/ui.gleam b/src/musicplayer/ui/ui.gleam index d271f1a..ed6e9d1 100644 --- a/src/musicplayer/ui/ui.gleam +++ b/src/musicplayer/ui/ui.gleam @@ -9,6 +9,7 @@ import musicplayer/logging/logging import musicplayer/ui/control.{type Control} import musicplayer/ui/internal import musicplayer/ui/layout.{type Layout} +import musicplayer/ui/style pub type State(redraw, content) { State(redraw: Subject(Layout), layout: Layout) @@ -25,10 +26,10 @@ pub fn new() -> Result(Subject(Control), String) { layout.Header, layout.Row( heading: Some("Foo <1> | Bar (2)"), - style: layout.Style(dimensions: layout.Percent( - width: 100, - height: 50, - )), + style: style.Style( + dimensions: style.Percent(width: 100, height: 50), + border: Some(style.BorderSingle), + ), children: [], ), ), @@ -36,10 +37,10 @@ pub fn new() -> Result(Subject(Control), String) { layout.PlaybackTime, layout.Row( heading: None, - style: layout.Style(dimensions: layout.Percent( - width: 100, - height: 50, - )), + style: style.Style( + dimensions: style.Percent(width: 100, height: 50), + border: Some(style.BorderSingle), + ), children: [], ), ), @@ -49,10 +50,10 @@ pub fn new() -> Result(Subject(Control), String) { layout.Header, layout.Row( heading: Some("Foo (1) | Bar <2>"), - style: layout.Style(dimensions: layout.Percent( - width: 100, - height: 33, - )), + style: style.Style( + dimensions: style.Percent(width: 100, height: 33), + border: Some(style.BorderSingle), + ), children: [], ), ), @@ -60,10 +61,10 @@ pub fn new() -> Result(Subject(Control), String) { layout.Search, layout.Row( heading: None, - style: layout.Style(dimensions: layout.Percent( - width: 100, - height: 33, - )), + style: style.Style( + dimensions: style.Percent(width: 100, height: 33), + border: Some(style.BorderSingle), + ), children: [], ), ), @@ -71,10 +72,10 @@ pub fn new() -> Result(Subject(Control), String) { layout.PlaybackTime, layout.Row( heading: None, - style: layout.Style(dimensions: layout.Percent( - width: 100, - height: 33, - )), + style: style.Style( + dimensions: style.Percent(width: 100, height: 33), + border: Some(style.BorderSingle), + ), children: [], ), ), diff --git a/test/musicplayer/ui/layout_test.gleam b/test/musicplayer/ui/layout_test.gleam index 9fc5490..c3ecdab 100644 --- a/test/musicplayer/ui/layout_test.gleam +++ b/test/musicplayer/ui/layout_test.gleam @@ -5,8 +5,9 @@ import gleam/string import gleeunit import gleeunit/should -import musicplayer/ui/layout.{Percent, RenderContext, Section, Style} +import musicplayer/ui/layout.{RenderContext, Section} import musicplayer/ui/plot +import musicplayer/ui/style.{Percent, Style} pub fn main() -> Nil { gleeunit.main() @@ -19,7 +20,10 @@ pub fn percent_layout_test() { Section("Row1"), layout.Row( heading: Some("row 1"), - style: Style(dimensions: Percent(width: 100, height: 50)), + style: Style( + dimensions: Percent(width: 100, height: 50), + border: Some(style.BorderSingle), + ), children: [ Section("A"), Section("B"), @@ -30,21 +34,30 @@ pub fn percent_layout_test() { Section("A"), layout.Cell( heading: Some("cell 1"), - style: Style(dimensions: Percent(width: 50, height: 100)), + style: Style( + dimensions: Percent(width: 50, height: 100), + border: Some(style.BorderSingle), + ), ), ), #( Section("B"), layout.Cell( heading: Some("cell 2"), - style: Style(dimensions: Percent(width: 50, height: 100)), + style: Style( + dimensions: Percent(width: 50, height: 100), + border: Some(style.BorderSingle), + ), ), ), #( Section("Row2"), layout.Row( heading: Some("row 1"), - style: Style(dimensions: Percent(width: 100, height: 50)), + style: Style( + dimensions: Percent(width: 100, height: 50), + border: Some(style.BorderSingle), + ), children: [], ), ),