Plot layout Views on grid #10
@@ -33,13 +33,41 @@ pub type Node {
|
|||||||
Cell(content: String, style: Style)
|
Cell(content: String, style: Style)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub type ViewIdx =
|
||||||
|
Int
|
||||||
|
|
||||||
|
pub type View =
|
||||||
|
dict.Dict(Section, Node)
|
||||||
|
|
||||||
|
// Layout consists of a list Views, and only one View is rendered at a time
|
||||||
pub type Layout {
|
pub type Layout {
|
||||||
Layout(columns: Int, rows: Int, nodes: dict.Dict(Section, Node))
|
Layout(
|
||||||
|
columns: Int,
|
||||||
|
rows: Int,
|
||||||
|
current_view: ViewIdx,
|
||||||
|
views: dict.Dict(ViewIdx, View),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new(columns: Int, rows: Int, nodes: List(#(Section, Node))) -> Layout {
|
pub fn new(
|
||||||
|
columns: Int,
|
||||||
|
rows: Int,
|
||||||
|
views: List(List(#(Section, Node))),
|
||||||
|
) -> Layout {
|
||||||
|
let views =
|
||||||
|
list.index_map(views, fn(view_nodes, i) { #(i, view_nodes) })
|
||||||
|
|> list.fold(dict.new(), fn(view_acc, iv) {
|
||||||
|
let #(i, view_nodes) = iv
|
||||||
|
|
||||||
|
dict.insert(view_acc, i, view_loop(i, view_nodes))
|
||||||
|
})
|
||||||
|
|
||||||
|
Layout(columns:, rows:, current_view: 0, views:)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn view_loop(i: ViewIdx, view_nodes: List(#(Section, Node))) -> View {
|
||||||
let children =
|
let children =
|
||||||
nodes
|
view_nodes
|
||||||
|> list.flat_map(fn(node) {
|
|> list.flat_map(fn(node) {
|
||||||
case pair.second(node) {
|
case pair.second(node) {
|
||||||
Row(children: c, ..) -> c
|
Row(children: c, ..) -> c
|
||||||
@@ -51,22 +79,19 @@ pub fn new(columns: Int, rows: Int, nodes: List(#(Section, Node))) -> Layout {
|
|||||||
// All sections that are not children of other nodes will be added as
|
// All sections that are not children of other nodes will be added as
|
||||||
// children to the root
|
// children to the root
|
||||||
let orphans =
|
let orphans =
|
||||||
nodes
|
view_nodes
|
||||||
|> list.map(pair.first)
|
|> list.map(pair.first)
|
||||||
|> list.filter(fn(node) { !set.contains(children, node) })
|
|> list.filter(fn(node) { !set.contains(children, node) })
|
||||||
|
|
||||||
let nodes =
|
dict.from_list(view_nodes)
|
||||||
dict.from_list(nodes)
|
|
||||||
|> dict.insert(
|
|> dict.insert(
|
||||||
Section(root_section),
|
Section(string.append("view_", string.inspect(i))),
|
||||||
Row(
|
Row(
|
||||||
content: "",
|
content: "",
|
||||||
style: Style(dimensions: Percent(width: 100, height: 100)),
|
style: Style(dimensions: Percent(width: 100, height: 100)),
|
||||||
children: orphans,
|
children: orphans,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
Layout(columns:, rows:, nodes:)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_section(
|
pub fn update_section(
|
||||||
@@ -74,15 +99,24 @@ pub fn update_section(
|
|||||||
section: Section,
|
section: Section,
|
||||||
content: String,
|
content: String,
|
||||||
) -> Layout {
|
) -> Layout {
|
||||||
case dict.get(layout.nodes, section) {
|
case dict.get(layout.views, layout.current_view) {
|
||||||
|
Error(_) -> layout
|
||||||
|
Ok(view) ->
|
||||||
|
case dict.get(view, section) {
|
||||||
Error(_) -> layout
|
Error(_) -> layout
|
||||||
Ok(node) -> {
|
Ok(node) -> {
|
||||||
let updated = case node {
|
let updated_node = case node {
|
||||||
Cell(..) -> Cell(..node, content: content)
|
Cell(..) -> Cell(..node, content: content)
|
||||||
Row(..) -> Row(..node, content: content)
|
Row(..) -> Row(..node, content: content)
|
||||||
}
|
}
|
||||||
|
|
||||||
Layout(..layout, nodes: dict.insert(layout.nodes, section, updated))
|
let updated_view = dict.insert(view, section, updated_node)
|
||||||
|
|
||||||
|
Layout(
|
||||||
|
..layout,
|
||||||
|
views: dict.insert(layout.views, layout.current_view, updated_view),
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -107,12 +141,22 @@ pub fn render(layout: Layout) -> Nil {
|
|||||||
position_index: 0,
|
position_index: 0,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
case dict.get(layout.views, layout.current_view) {
|
||||||
|
Error(_) -> Nil
|
||||||
|
Ok(view) -> {
|
||||||
let buffer: Buffer = dict.new()
|
let buffer: Buffer = dict.new()
|
||||||
|
|
||||||
render_loop(layout, context, Section(root_section), buffer)
|
render_loop(
|
||||||
|
view,
|
||||||
|
context,
|
||||||
|
Section(string.append("view_", string.inspect(layout.current_view))),
|
||||||
|
buffer,
|
||||||
|
)
|
||||||
|> plot.flush_buffer(layout.columns, layout.rows)
|
|> plot.flush_buffer(layout.columns, layout.rows)
|
||||||
|> internal.update
|
|> internal.update
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub type RenderContext {
|
pub type RenderContext {
|
||||||
RenderContext(
|
RenderContext(
|
||||||
@@ -125,12 +169,12 @@ pub type RenderContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn render_loop(
|
pub fn render_loop(
|
||||||
layout: Layout,
|
view: View,
|
||||||
context: RenderContext,
|
context: RenderContext,
|
||||||
from: Section,
|
from: Section,
|
||||||
buffer: Buffer,
|
buffer: Buffer,
|
||||||
) -> Buffer {
|
) -> Buffer {
|
||||||
case dict.get(layout.nodes, from) {
|
case dict.get(view, from) {
|
||||||
Error(_) -> buffer
|
Error(_) -> buffer
|
||||||
Ok(node) -> {
|
Ok(node) -> {
|
||||||
// Margin between container and the node being rendered
|
// Margin between container and the node being rendered
|
||||||
@@ -193,7 +237,7 @@ pub fn render_loop(
|
|||||||
position_index: i,
|
position_index: i,
|
||||||
)
|
)
|
||||||
|
|
||||||
render_loop(layout, context, child, acc_buffer)
|
render_loop(view, context, child, acc_buffer)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,8 @@ pub fn main() {
|
|||||||
/// First row has two cells
|
/// First row has two cells
|
||||||
/// Second row has no cells
|
/// Second row has no cells
|
||||||
fn two_rows_with_cells(columns: Int, rows: Int) -> layout.Layout {
|
fn two_rows_with_cells(columns: Int, rows: Int) -> layout.Layout {
|
||||||
let nodes = [
|
let views = [
|
||||||
|
[
|
||||||
#(
|
#(
|
||||||
Section("Row1"),
|
Section("Row1"),
|
||||||
layout.Row(
|
layout.Row(
|
||||||
@@ -50,7 +51,8 @@ fn two_rows_with_cells(columns: Int, rows: Int) -> layout.Layout {
|
|||||||
children: [],
|
children: [],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
],
|
||||||
]
|
]
|
||||||
|
|
||||||
layout.new(columns, rows, nodes)
|
layout.new(columns, rows, views)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,12 +18,16 @@ pub fn new() -> Result(Subject(Control), String) {
|
|||||||
let redraw: Subject(Layout) = process.named_subject(redraw_name)
|
let redraw: Subject(Layout) = process.named_subject(redraw_name)
|
||||||
|
|
||||||
let layout =
|
let layout =
|
||||||
|
[
|
||||||
[
|
[
|
||||||
#(
|
#(
|
||||||
layout.Header,
|
layout.Header,
|
||||||
layout.Row(
|
layout.Row(
|
||||||
content: "Foo (1) | Bar (2) | Baz (3)",
|
content: "Foo (1) | Bar (2) | Baz (3)",
|
||||||
style: layout.Style(dimensions: layout.Percent(width: 100, height: 33)),
|
style: layout.Style(dimensions: layout.Percent(
|
||||||
|
width: 100,
|
||||||
|
height: 33,
|
||||||
|
)),
|
||||||
children: [],
|
children: [],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -31,7 +35,10 @@ pub fn new() -> Result(Subject(Control), String) {
|
|||||||
layout.Search,
|
layout.Search,
|
||||||
layout.Row(
|
layout.Row(
|
||||||
content: "",
|
content: "",
|
||||||
style: layout.Style(dimensions: layout.Percent(width: 100, height: 33)),
|
style: layout.Style(dimensions: layout.Percent(
|
||||||
|
width: 100,
|
||||||
|
height: 33,
|
||||||
|
)),
|
||||||
children: [],
|
children: [],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -39,10 +46,14 @@ pub fn new() -> Result(Subject(Control), String) {
|
|||||||
layout.PlaybackTime,
|
layout.PlaybackTime,
|
||||||
layout.Row(
|
layout.Row(
|
||||||
content: "00:00",
|
content: "00:00",
|
||||||
style: layout.Style(dimensions: layout.Percent(width: 100, height: 33)),
|
style: layout.Style(dimensions: layout.Percent(
|
||||||
|
width: 100,
|
||||||
|
height: 33,
|
||||||
|
)),
|
||||||
children: [],
|
children: [],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
],
|
||||||
]
|
]
|
||||||
|> layout.new(0, 0, _)
|
|> layout.new(0, 0, _)
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,8 @@ pub fn main() -> Nil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn percent_layout_test() {
|
pub fn percent_layout_test() {
|
||||||
let nodes = [
|
let views = [
|
||||||
|
[
|
||||||
#(
|
#(
|
||||||
Section("Row1"),
|
Section("Row1"),
|
||||||
layout.Row(
|
layout.Row(
|
||||||
@@ -46,11 +47,12 @@ pub fn percent_layout_test() {
|
|||||||
children: [],
|
children: [],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
],
|
||||||
]
|
]
|
||||||
|
|
||||||
let columns = 80
|
let columns = 80
|
||||||
let rows = 20
|
let rows = 20
|
||||||
let layout = layout.new(columns, rows, nodes)
|
let layout = layout.new(columns, rows, views)
|
||||||
|
|
||||||
let expected =
|
let expected =
|
||||||
"
|
"
|
||||||
@@ -87,11 +89,13 @@ pub fn percent_layout_test() {
|
|||||||
position_index: 0,
|
position_index: 0,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
let assert Ok(view) = dict.get(layout.views, layout.current_view)
|
||||||
|
|
||||||
let flushed =
|
let flushed =
|
||||||
layout.render_loop(
|
layout.render_loop(
|
||||||
layout,
|
view,
|
||||||
context,
|
context,
|
||||||
Section(layout.root_section),
|
Section(string.append("view_", string.inspect(layout.current_view))),
|
||||||
dict.new(),
|
dict.new(),
|
||||||
)
|
)
|
||||||
|> plot.flush_buffer(layout.columns, layout.rows)
|
|> plot.flush_buffer(layout.columns, layout.rows)
|
||||||
|
|||||||
Reference in New Issue
Block a user