2 Commits

Author SHA1 Message Date
Alexander Heldt
68bf808635 Move styling to style and add Border type 2025-12-26 12:13:11 +01:00
Alexander Heldt
4329625cf4 Add margin to box headings 2025-12-26 11:56:24 +01:00
6 changed files with 98 additions and 44 deletions

View File

@@ -8,6 +8,7 @@ import gleam/string
import musicplayer/ui/internal import musicplayer/ui/internal
import musicplayer/ui/plot.{type Buffer} import musicplayer/ui/plot.{type Buffer}
import musicplayer/ui/style.{type Style, Percent, Style}
pub const root_section = "reserved_root_section" pub const root_section = "reserved_root_section"
@@ -19,15 +20,6 @@ pub type Section {
PlaybackTime PlaybackTime
} }
pub type Dimension {
Percent(width: Int, height: Int)
// TODO add Flex that flows
}
pub type Style {
Style(dimensions: Dimension)
}
pub type Node { pub type Node {
Row(heading: Option(String), style: Style, children: List(Section)) Row(heading: Option(String), style: Style, children: List(Section))
Cell(heading: Option(String), style: Style) 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), view_index_section(i),
Row( Row(
heading: None, heading: None,
style: Style(dimensions: Percent(width: 100, height: 100)), style: Style(dimensions: Percent(width: 100, height: 100), border: None),
children: orphans, children: orphans,
), ),
) )

View File

@@ -1,8 +1,9 @@
import gleam/option.{Some} import gleam/option.{Some}
import musicplayer/ui/internal 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/layout_examples/wait_for_input.{wait_for_input}
import musicplayer/ui/style.{Percent, Style}
pub fn main() { pub fn main() {
let assert Ok(columns) = internal.io_get_columns() 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"), Section("Row1"),
layout.Row( layout.Row(
heading: Some("row 1"), 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: [ children: [
Section("A"), Section("A"),
Section("B"), Section("B"),
@@ -35,21 +39,30 @@ fn two_rows_with_cells(columns: Int, rows: Int) -> layout.Layout {
Section("A"), Section("A"),
layout.Cell( layout.Cell(
heading: Some("cell 1"), 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"), Section("B"),
layout.Cell( layout.Cell(
heading: Some("cell 2"), 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"), Section("Row2"),
layout.Row( layout.Row(
heading: Some("row 2"), 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: [], children: [],
), ),
), ),

View File

@@ -57,8 +57,9 @@ pub fn box_with_heading(
height: Int, height: Int,
heading: String, heading: String,
) -> Buffer { ) -> Buffer {
let heading_margin = 1
box(buffer, x, y, width, height) box(buffer, x, y, width, height)
|> text(heading, x, y) |> text(heading, x + heading_margin, y)
} }
fn horizontal_line( fn horizontal_line(

View File

@@ -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("", "", "", "", "", "")
}
}

View File

@@ -9,6 +9,7 @@ import musicplayer/logging/logging
import musicplayer/ui/control.{type Control} import musicplayer/ui/control.{type Control}
import musicplayer/ui/internal import musicplayer/ui/internal
import musicplayer/ui/layout.{type Layout} import musicplayer/ui/layout.{type Layout}
import musicplayer/ui/style
pub type State(redraw, content) { pub type State(redraw, content) {
State(redraw: Subject(Layout), layout: Layout) State(redraw: Subject(Layout), layout: Layout)
@@ -25,10 +26,10 @@ pub fn new() -> Result(Subject(Control), String) {
layout.Header, layout.Header,
layout.Row( layout.Row(
heading: Some("Foo <1> | Bar (2)"), heading: Some("Foo <1> | Bar (2)"),
style: layout.Style(dimensions: layout.Percent( style: style.Style(
width: 100, dimensions: style.Percent(width: 100, height: 50),
height: 50, border: Some(style.BorderSingle),
)), ),
children: [], children: [],
), ),
), ),
@@ -36,10 +37,10 @@ pub fn new() -> Result(Subject(Control), String) {
layout.PlaybackTime, layout.PlaybackTime,
layout.Row( layout.Row(
heading: None, heading: None,
style: layout.Style(dimensions: layout.Percent( style: style.Style(
width: 100, dimensions: style.Percent(width: 100, height: 50),
height: 50, border: Some(style.BorderSingle),
)), ),
children: [], children: [],
), ),
), ),
@@ -49,10 +50,10 @@ pub fn new() -> Result(Subject(Control), String) {
layout.Header, layout.Header,
layout.Row( layout.Row(
heading: Some("Foo (1) | Bar <2>"), heading: Some("Foo (1) | Bar <2>"),
style: layout.Style(dimensions: layout.Percent( style: style.Style(
width: 100, dimensions: style.Percent(width: 100, height: 33),
height: 33, border: Some(style.BorderSingle),
)), ),
children: [], children: [],
), ),
), ),
@@ -60,10 +61,10 @@ pub fn new() -> Result(Subject(Control), String) {
layout.Search, layout.Search,
layout.Row( layout.Row(
heading: None, heading: None,
style: layout.Style(dimensions: layout.Percent( style: style.Style(
width: 100, dimensions: style.Percent(width: 100, height: 33),
height: 33, border: Some(style.BorderSingle),
)), ),
children: [], children: [],
), ),
), ),
@@ -71,10 +72,10 @@ pub fn new() -> Result(Subject(Control), String) {
layout.PlaybackTime, layout.PlaybackTime,
layout.Row( layout.Row(
heading: None, heading: None,
style: layout.Style(dimensions: layout.Percent( style: style.Style(
width: 100, dimensions: style.Percent(width: 100, height: 33),
height: 33, border: Some(style.BorderSingle),
)), ),
children: [], children: [],
), ),
), ),

View File

@@ -5,8 +5,9 @@ import gleam/string
import gleeunit import gleeunit
import gleeunit/should import gleeunit/should
import musicplayer/ui/layout.{Percent, RenderContext, Section, Style} import musicplayer/ui/layout.{RenderContext, Section}
import musicplayer/ui/plot import musicplayer/ui/plot
import musicplayer/ui/style.{Percent, Style}
pub fn main() -> Nil { pub fn main() -> Nil {
gleeunit.main() gleeunit.main()
@@ -19,7 +20,10 @@ pub fn percent_layout_test() {
Section("Row1"), Section("Row1"),
layout.Row( layout.Row(
heading: Some("row 1"), 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: [ children: [
Section("A"), Section("A"),
Section("B"), Section("B"),
@@ -30,21 +34,30 @@ pub fn percent_layout_test() {
Section("A"), Section("A"),
layout.Cell( layout.Cell(
heading: Some("cell 1"), 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"), Section("B"),
layout.Cell( layout.Cell(
heading: Some("cell 2"), 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"), Section("Row2"),
layout.Row( layout.Row(
heading: Some("row 1"), 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: [], children: [],
), ),
), ),
@@ -58,8 +71,8 @@ pub fn percent_layout_test() {
let expected = let expected =
" "
┌──────────────────────────────────────────────────────────────────────────────┐ ┌──────────────────────────────────────────────────────────────────────────────┐
│row 1───────────────────────────────────────────────────────────────────────┐│ row 1───────────────────────────────────────────────────────────────────────┐│
││cell 1──────────────────────────────┐cell 2──────────────────────────────┐││ ││cell 1──────────────────────────────┐cell 2──────────────────────────────┐││
│││ ││ │││ │││ ││ │││
│││ ││ │││ │││ ││ │││
│││ ││ │││ │││ ││ │││
@@ -67,7 +80,7 @@ pub fn percent_layout_test() {
│││ ││ │││ │││ ││ │││
││└────────────────────────────────────┘└────────────────────────────────────┘││ ││└────────────────────────────────────┘└────────────────────────────────────┘││
│└────────────────────────────────────────────────────────────────────────────┘│ │└────────────────────────────────────────────────────────────────────────────┘│
│row 1───────────────────────────────────────────────────────────────────────┐│ row 1───────────────────────────────────────────────────────────────────────┐│
││ ││ ││ ││
││ ││ ││ ││
││ ││ ││ ││