modularize grid view

This commit is contained in:
i do not exist 2026-09-17 16:53:28 +03:00
parent 922c2e1f2f
commit 5a34025277
4 changed files with 173 additions and 104 deletions

View file

@ -2,28 +2,28 @@ use crate::*;
pub fn get_dialog <'a> (_: &App, src: impl Language) -> Perhaps<Dialog> {
src.word()?.map(|word|Ok(match word {
":dialog/none" => Dialog::None,
":dialog/options" => Dialog::Options,
":dialog/device" => Dialog::Device(0),
":dialog/device/prev" => Dialog::Device(0),
":dialog/device/next" => Dialog::Device(0),
":dialog/help" => Dialog::Help(0),
":dialog/save" => Dialog::Browse(
":none" => Dialog::None,
":options" => Dialog::Options,
":device" => Dialog::Device(0),
":device/prev" => Dialog::Device(0),
":device/next" => Dialog::Device(0),
":help" => Dialog::Help(0),
":save" => Dialog::Browse(
BrowseTarget::SaveProject,
Browse::new(None).unwrap().into()),
":dialog/load" => Dialog::Browse(
":load" => Dialog::Browse(
BrowseTarget::LoadProject,
Browse::new(None).unwrap().into()),
":dialog/import/clip" => Dialog::Browse(
":import/clip" => Dialog::Browse(
BrowseTarget::ImportClip(Default::default()),
Browse::new(None).unwrap().into()),
":dialog/export/clip" => Dialog::Browse(
":export/clip" => Dialog::Browse(
BrowseTarget::ExportClip(Default::default()),
Browse::new(None).unwrap().into()),
":dialog/import/sample" => Dialog::Browse(
":import/sample" => Dialog::Browse(
BrowseTarget::ImportSample(Default::default()),
Browse::new(None).unwrap().into()),
":dialog/export/sample" => Dialog::Browse(
":export/sample" => Dialog::Browse(
BrowseTarget::ExportSample(Default::default()),
Browse::new(None).unwrap().into()),
_ => return Err(
@ -89,6 +89,12 @@ impl Dialog {
modes: vec![":arranger".into()]
}
},
AppCommand::Tracks {
command: TracksCommand::Add
},
AppCommand::Scenes {
command: ScenesCommand::Add
}
]),
MenuItem::new(" Load session ", [

View file

@ -15,10 +15,11 @@
(info Mode selector.)
(keys :axis/y :confirm)
(view
(bar/n 2 (bsp/e :transport :status)
(bar/s 2 (pad/x 1 :transport)
(bar/n 2 :status
(align/c
(bar/s 2 (align/x (bg (g 12) :logo))
:dialog/menu)))))
:dialog/menu))))))
(keys :back (@escape cancel))
(keys :confirm (@enter confirm))
@ -39,16 +40,28 @@
(mode :scene (keys :scene))
(mode :mix (keys :mix))
(view
(bar/n 2 (bsp/e :transport :status)
(bar/s 2 :tracks/outputs
(bar/s 2 :tracks/devices
(bar/s 2 :tracks/names
(bar/n 2 :tracks/inputs
(bar/e 16 :scenes/names :scenes/clips))))))))
(bar/n 2 :status
(bar/s 8
(bar/e 16 (align/nw (pad/x 1 :transport))
(bar/w 16 (bar/s 2 (bar/w 4 :tracks/outputs/add :tracks/outputs/count)
(bar/s 2 (bar/w 4 :tracks/devices/add :tracks/devices/count)
(bar/s 2 (bar/w 4 :tracks/names/add :tracks/names/count)
(bar/w 4 :tracks/inputs/add :tracks/inputs/count))))
(align/x (bar/s 2 :tracks/outputs/cells
(bar/s 2 :tracks/devices/cells
(bar/s 2 :tracks/names/cells
:tracks/inputs/cells))))))
(bar/w 16 (text)
(bar/e 16 :scenes/names
:scenes/clips))))))
(keys :global
(@f1 (dialog :help))
(@f2 (project new))
(@f3 (dialog :history))
(@f6 (dialog :save))
(@f8 (dialog :options))
(@f9 (dialog :load))
(@f10 (dialog :quit)))
(keys :clock
@ -56,10 +69,10 @@
(@shift/space (clock/toggle 0)))
(keys :color
(@c color))
(@c (color)))
(keys :launch
(@q launch))
(@q (launch)))
(keys :scenes
(@shift/S (scenes add))
@ -155,8 +168,8 @@
(@shift/R sampler/record/back))
(keys :sampler/play (@p sampler/play/sample :sample/selected)
(@P sampler/stop/sample :sample/selected))
(keys :sampler/import-export (@shift/f6 dialog :dialog/export/sample)
(@shift/f9 dialog :dialog/import/sample))
(keys :sampler/import-export (@shift/f6 dialog :export/sample)
(@shift/f9 dialog :import/sample))
(keys :sampler/directions (@up sampler/select :sample/above)
(@down sampler/select :sample/below)
(@left sampler/select :sample/to/left)

View file

@ -369,14 +369,22 @@ pub trait TracksView: HasTracks + ScenesView + HasMidiIns + HasMidiOuts + HasTra
/// Draw name of each track
fn view_track_names (&self, theme: ItemTheme) -> impl Draw<Tui> {
let btn1t = self.view_track_count();
let btn1s = self.view_scene_count();
let btns1 = south(btn1t, btn1s);
let btns2 = south(self.view_track_add(), self.view_scene_add());
view_track_row_section(theme,
btns1,
btns2,
bg(theme.darker.term,
self.view_track_names_count(),
self.view_track_names_add(),
self.view_track_names_cells()
)
}
fn view_track_names_add (&self) -> impl Draw<Tui> {
south(self.view_track_add(), self.view_scene_add())
}
fn view_track_names_count (&self) -> impl Draw<Tui> {
south(self.view_track_count(), self.view_scene_count())
}
fn view_track_names_cells <'a> (&'a self) -> impl Draw<Tui> {
iter_east(||self.tracks_with_sizes().map(|(index, track, _x1, _x2)|{
let b = if self.selection().track() == Some(index) {
track.color.light.term
@ -396,7 +404,7 @@ pub trait TracksView: HasTracks + ScenesView + HasMidiIns + HasMidiOuts + HasTra
))
.exact_w(track_width(index, track))
.exact_h(2)
}))))
}))
}
/// Draw outputs per track
@ -404,7 +412,11 @@ pub trait TracksView: HasTracks + ScenesView + HasMidiIns + HasMidiOuts + HasTra
view_track_row_section(theme,
self.view_track_output_count(),
self.view_track_output_add(),
bg(theme.darker.term,
self.view_track_output_cells()
)
}
fn view_track_output_cells <'a> (&'a self) -> impl Draw<Tui> {
iter_east(move||self.tracks_with_sizes().map(move|(index, track, _x1, _x2)|{
let f = Rgb(255, 255, 255);
let b = track.color.dark.term;
@ -414,19 +426,71 @@ pub trait TracksView: HasTracks + ScenesView + HasMidiIns + HasMidiOuts + HasTra
.full_h()
.align_nw()
.exact_w(track_width(index, track))
}))))
}))
}
/// Draw inputs per track
fn view_track_inputs <'a> (&'a self, theme: ItemTheme) -> impl Draw<Tui> {
fn view_track_device_count (&self) -> impl Draw<Tui> {
button_3("d", "evice", self.track().map(|t|t.devices.len()).unwrap_or(0), false).min_h(2)
}
fn view_track_devices (&self, theme: ItemTheme) -> impl Draw<Tui> {
let height = self.tracks_devices_height();
let btn1 = self.view_track_device_count();
let btn2 = self.view_track_device_add();
view_track_row_section(theme, btn1, btn2, self.view_track_device_cells(height))
}
fn view_track_device_cells (&self, height: u16) -> impl Draw<Tui> {
iter_east(move||self.tracks_with_sizes()
.enumerate()
.map(move|(index, (_, track, _x1, _x2))|bg(
track.color.dark.term,
iter_south(move||(0..height).map(|_|fg_bg(
ItemTheme::G[32].lightest.term,
ItemTheme::G[32].dark.term,
" · --".align_nw()
).exact_wh(track.width as u16, 2)))
.align_nw()
)
.exact_wh(
Some(track_width(index, track)),
Some(height + 1),
)))
}
fn tracks_devices_height (&self) -> u16 {
let mut h = 2;
for track in self.tracks().iter() {
h = h.max(track.devices.len() * 2);
}
h as u16
}
fn view_inputs (&self) -> impl Draw<Tui> + '_ {
let title_1 = button_3("i", "nput ", self.midi_ins().len(), false).align_w().exact_wh(20, 1);
let title_2 = self.view_track_input_add().exact_wh(4, 1);
east(title_1, west(title_2, self.view_input_cells()))
}
fn tracks_inputs_height (&self) -> u16 {
let mut height = 0u16;
for track in self.tracks().iter() {
height = height.max(track.sequencer.midi_ins.len() as u16);
}
height
}
/// Draw inputs per track
fn view_track_inputs <'a> (&'a self, theme: ItemTheme) -> impl Draw<Tui> {
view_track_row_section(theme,
self.view_track_input_count(),
self.view_track_input_add(),
bg(theme.darker.term, iter_east(move||self
self.view_track_input_cells(self.tracks_inputs_height())
)
}
fn view_track_input_cells (&self, height: u16) -> impl Draw<Tui> {
iter_east(move||self
.tracks_with_sizes()
.map(move|(index, track, _x1, _x2)|{
south(
@ -442,42 +506,11 @@ pub trait TracksView: HasTracks + ScenesView + HasMidiIns + HasMidiOuts + HasTra
east!("·i", index, " ", port.port_name()).align_w().full_w()))))
.align_nw()
.exact_wh(track_width(index, track), height + 1)
}))).align_w())
})).align_w()
}
fn view_track_devices (&self, theme: ItemTheme) -> impl Draw<Tui> {
let height = self.tracks_devices_height();
let btn1 = button_3("d", "evice", self.track().map(|t|t.devices.len()).unwrap_or(0), false).min_h(2);
let btn2 = self.view_track_device_add();
view_track_row_section(theme, btn1, btn2, iter_east(move||self.tracks_with_sizes()
.enumerate()
.map(move|(index, (_, track, _x1, _x2))|bg(
track.color.dark.term,
iter_south(move||(0..height).map(|_|fg_bg(
ItemTheme::G[32].lightest.term,
ItemTheme::G[32].dark.term,
" · --".align_nw()
).exact_wh(track.width as u16, 2)))
.align_nw()
)
.exact_wh(
Some(track_width(index, track)),
Some(height + 1),
))))
}
fn tracks_devices_height (&self) -> u16 {
let mut h = 2;
for track in self.tracks().iter() {
h = h.max(track.devices.len() * 2);
}
h as u16
}
fn view_inputs (&self, _theme: ItemTheme) -> impl Draw<Tui> + '_ {
let title_1 = button_3("i", "nput ", self.midi_ins().len(), false).align_w().exact_wh(20, 1);
let title_2 = self.view_track_input_add().exact_wh(4, 1);
east(title_1, west(title_2, draw(move|to: &mut Tui|{
fn view_input_cells (&self) -> impl Draw<Tui> {
draw(move|to: &mut Tui|{
for (_index, track, x1, _x2) in self.tracks_with_sizes() {
let _ = south(
bg(track.color.dark.term, east!(
@ -502,12 +535,12 @@ pub trait TracksView: HasTracks + ScenesView + HasMidiIns + HasMidiOuts + HasTra
)
).push_x(index as u16 * 10).exact_h(1).draw(to)?;
}
todo!()
Ok(None)
})
).draw(to)?;
}
Ok(Some(to.area()))
})))
})
}
fn outputs_height (&self) -> u16 {

View file

@ -262,13 +262,30 @@ impl View<Tui, App> {
Some("output") => Self::boxed(move|_, to|bg(Rgb(30, 30, 30), "Output Meters".align_s().full_h()).draw(to)),
_ => panic!()
},
Some(":tracks") => match word.split("/").skip(1).next() {
None => Self::boxed(move|_, to|"TODO tracks".draw(to)),
Some("names") => draw!(|app|app.project.view_track_names(app.color.clone())),
Some("inputs") => draw!(|app|app.project.view_track_inputs(app.color.clone())),
Some("devices") => draw!(|app|app.project.view_track_devices(app.color.clone())),
Some("outputs") => draw!(|app|app.project.view_track_outputs(app.color.clone(), 0)),
_ => panic!()
Some(":tracks") => match &word[(":tracks".len()+1)..] {
"" => Self::boxed(move|_, to|"TODO tracks".draw(to)),
"names" => draw!(|app|app.project.view_track_names(app.color.clone())),
"names/count" => draw!(|app|app.project.view_track_names_count()),
"names/cells" => draw!(|app|app.project.view_track_names_cells()),
"names/add" => draw!(|app|app.project.view_track_names_add()),
"devices" => draw!(|app|app.project.view_track_devices(app.color.clone())),
"devices/count" => draw!(|app|app.project.view_track_device_count()),
"devices/cells" => draw!(|app|app.project.view_track_device_cells(app.tracks_devices_height())),
"devices/add" => draw!(|app|app.project.view_track_device_add()),
"inputs" => draw!(|app|app.project.view_track_inputs(app.color.clone())),
"inputs/count" => draw!(|app|app.project.view_track_input_count()),
"inputs/cells" => draw!(|app|app.project.view_track_input_cells(app.tracks_inputs_height())),
"inputs/add" => draw!(|app|app.project.view_track_input_add()),
"outputs" => draw!(|app|app.project.view_track_outputs(app.color.clone(), 0)),
"outputs/count" => draw!(|app|app.project.view_track_output_count()),
"outputs/cells" => draw!(|app|app.project.view_track_output_cells()),
"outputs/add" => draw!(|app|app.project.view_track_output_add()),
_ => panic!("unknown: {word}")
},
Some(":scenes") => match word.split("/").skip(1).next() {
Some("clips") => draw!(|app|app.view_scenes_clips()),