Add ability to switch View
This commit was merged in pull request #10.
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
import gleam/string
|
import gleam/string
|
||||||
|
import musicplayer/ui/layout
|
||||||
|
|
||||||
import musicplayer/input/key.{type Key}
|
import musicplayer/input/key.{type Key}
|
||||||
|
|
||||||
@@ -11,6 +12,8 @@ pub type Control {
|
|||||||
TogglePlayPause
|
TogglePlayPause
|
||||||
Search(input: String, capturing: Bool)
|
Search(input: String, capturing: Bool)
|
||||||
|
|
||||||
|
SetView(view_idx: layout.ViewIdx)
|
||||||
|
|
||||||
Exit
|
Exit
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -25,6 +28,10 @@ pub fn idle_from_key(key: Key) -> Result(Control, Nil) {
|
|||||||
case key {
|
case key {
|
||||||
key.Char(char) -> {
|
key.Char(char) -> {
|
||||||
case char {
|
case char {
|
||||||
|
// Views are zero indexed
|
||||||
|
"1" -> Ok(SetView(0))
|
||||||
|
"2" -> Ok(SetView(1))
|
||||||
|
|
||||||
" " -> Ok(TogglePlayPause)
|
" " -> Ok(TogglePlayPause)
|
||||||
"/" -> Ok(Search(input: "", capturing: True))
|
"/" -> Ok(Search(input: "", capturing: True))
|
||||||
"q" -> Ok(Exit)
|
"q" -> Ok(Exit)
|
||||||
|
|||||||
@@ -51,6 +51,15 @@ fn handle_message(state: State, key: Key) -> actor.Next(State, Key) {
|
|||||||
Error(_) -> actor.continue(state)
|
Error(_) -> actor.continue(state)
|
||||||
Ok(c) ->
|
Ok(c) ->
|
||||||
case c {
|
case c {
|
||||||
|
control.SetView(view_idx) -> {
|
||||||
|
logging.log(
|
||||||
|
"musicplayer - setting current view to: "
|
||||||
|
<> string.inspect(view_idx),
|
||||||
|
)
|
||||||
|
|
||||||
|
update_current_view(state.ui, view_idx)
|
||||||
|
actor.continue(state)
|
||||||
|
}
|
||||||
control.Search(input, capturing) -> {
|
control.Search(input, capturing) -> {
|
||||||
case capturing {
|
case capturing {
|
||||||
True -> {
|
True -> {
|
||||||
@@ -146,6 +155,13 @@ fn update_search(ui: Subject(ui_control.Control), content: String) -> Nil {
|
|||||||
process.send(ui, ui_control.UpdateState(layout.Search, content))
|
process.send(ui, ui_control.UpdateState(layout.Search, content))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn update_current_view(
|
||||||
|
ui: Subject(ui_control.Control),
|
||||||
|
view_idx: layout.ViewIdx,
|
||||||
|
) {
|
||||||
|
process.send(ui, ui_control.SetView(view_idx))
|
||||||
|
}
|
||||||
|
|
||||||
/// `forward_key` listens to a subject onto which `input` will send messages with `Key`s
|
/// `forward_key` listens to a subject onto which `input` will send messages with `Key`s
|
||||||
/// that is then forwarded to the `musicplayer` agent to handle
|
/// that is then forwarded to the `musicplayer` agent to handle
|
||||||
fn forward_key(musicplayer: Subject(Key), input_keys: Subject(Key)) -> Nil {
|
fn forward_key(musicplayer: Subject(Key), input_keys: Subject(Key)) -> Nil {
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import gleam/erlang/process.{type Subject}
|
import gleam/erlang/process.{type Subject}
|
||||||
|
|
||||||
import musicplayer/ui/layout.{type Section}
|
import musicplayer/ui/layout.{type Section, type ViewIdx}
|
||||||
|
|
||||||
pub type Control {
|
pub type Control {
|
||||||
UpdateDimensions(columns: Int, rows: Int)
|
UpdateDimensions(columns: Int, rows: Int)
|
||||||
UpdateState(section: Section, content: String)
|
UpdateState(section: Section, content: String)
|
||||||
SetView(view_idx: layout.ViewIdx)
|
SetView(view_idx: ViewIdx)
|
||||||
|
|
||||||
Exit(reply_to: Subject(Nil))
|
Exit(reply_to: Subject(Nil))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import gleam/dict
|
import gleam/dict
|
||||||
|
import gleam/int
|
||||||
import gleam/list
|
import gleam/list
|
||||||
import gleam/pair
|
import gleam/pair
|
||||||
import gleam/set
|
import gleam/set
|
||||||
@@ -83,7 +84,7 @@ fn view_loop(i: ViewIdx, view_nodes: List(#(Section, Node))) -> View {
|
|||||||
|
|
||||||
dict.from_list(view_nodes)
|
dict.from_list(view_nodes)
|
||||||
|> dict.insert(
|
|> dict.insert(
|
||||||
Section(string.append("view_", string.inspect(i))),
|
view_index_section(i),
|
||||||
Row(
|
Row(
|
||||||
content: "",
|
content: "",
|
||||||
style: Style(dimensions: Percent(width: 100, height: 100)),
|
style: Style(dimensions: Percent(width: 100, height: 100)),
|
||||||
@@ -92,6 +93,11 @@ fn view_loop(i: ViewIdx, view_nodes: List(#(Section, Node))) -> View {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Takes a ViewIndex and create a Section key from it
|
||||||
|
fn view_index_section(view_idx: ViewIdx) -> Section {
|
||||||
|
Section(string.append("view_", int.to_string(view_idx)))
|
||||||
|
}
|
||||||
|
|
||||||
pub fn update_section(
|
pub fn update_section(
|
||||||
layout: Layout,
|
layout: Layout,
|
||||||
section: Section,
|
section: Section,
|
||||||
@@ -123,7 +129,7 @@ pub fn update_dimensions(layout: Layout, columns: Int, rows: Int) -> Layout {
|
|||||||
Layout(..layout, columns:, rows:)
|
Layout(..layout, columns:, rows:)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_view(layout: Layout, view_idx: ViewIdx) -> Layout {
|
pub fn update_current_view(layout: Layout, view_idx: ViewIdx) -> Layout {
|
||||||
Layout(..layout, current_view: view_idx)
|
Layout(..layout, current_view: view_idx)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -145,8 +151,7 @@ pub fn render(layout: Layout) -> Nil {
|
|||||||
render_loop(
|
render_loop(
|
||||||
view,
|
view,
|
||||||
context,
|
context,
|
||||||
// TODO extract to function `view_index`
|
view_index_section(layout.current_view),
|
||||||
Section(string.append("view_", string.inspect(layout.current_view))),
|
|
||||||
buffer,
|
buffer,
|
||||||
)
|
)
|
||||||
|> plot.flush_buffer(layout.columns, layout.rows)
|
|> plot.flush_buffer(layout.columns, layout.rows)
|
||||||
|
|||||||
@@ -23,7 +23,31 @@ pub fn new() -> Result(Subject(Control), String) {
|
|||||||
#(
|
#(
|
||||||
layout.Header,
|
layout.Header,
|
||||||
layout.Row(
|
layout.Row(
|
||||||
content: "Foo (1) | Bar (2) | Baz (3)",
|
content: "Foo <1> | Bar (2)",
|
||||||
|
style: layout.Style(dimensions: layout.Percent(
|
||||||
|
width: 100,
|
||||||
|
height: 50,
|
||||||
|
)),
|
||||||
|
children: [],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
#(
|
||||||
|
layout.PlaybackTime,
|
||||||
|
layout.Row(
|
||||||
|
content: "00:00",
|
||||||
|
style: layout.Style(dimensions: layout.Percent(
|
||||||
|
width: 100,
|
||||||
|
height: 50,
|
||||||
|
)),
|
||||||
|
children: [],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
#(
|
||||||
|
layout.Header,
|
||||||
|
layout.Row(
|
||||||
|
content: "Foo (1) | Bar <2>",
|
||||||
style: layout.Style(dimensions: layout.Percent(
|
style: layout.Style(dimensions: layout.Percent(
|
||||||
width: 100,
|
width: 100,
|
||||||
height: 33,
|
height: 33,
|
||||||
@@ -121,7 +145,7 @@ fn handle_message(
|
|||||||
actor.stop()
|
actor.stop()
|
||||||
}
|
}
|
||||||
control.SetView(view_idx) -> {
|
control.SetView(view_idx) -> {
|
||||||
let layout = layout.set_view(state.layout, view_idx)
|
let layout = layout.update_current_view(state.layout, view_idx)
|
||||||
|
|
||||||
actor.send(state.redraw, layout)
|
actor.send(state.redraw, layout)
|
||||||
actor.continue(State(..state, layout:))
|
actor.continue(State(..state, layout:))
|
||||||
|
|||||||
Reference in New Issue
Block a user