arranger: cursor highlight

This commit is contained in:
🪞👃🪞 2025-05-17 11:48:54 +03:00
parent a9288cb0c2
commit b663c53b0a
2 changed files with 125 additions and 80 deletions

View file

@ -214,7 +214,10 @@ pub trait TracksView: HasSize<TuiOut> + HasTrackScroll + HasSelection + HasMidiI
}
}))))));
Bsp::w(
self.view_track_header(theme, row!(Tui::bold(true, "[t]rack "), "[T] +")),
self.view_track_header(theme, row!(
Tui::bold(true, button_2("t", "rack ", false)),
button_2("T", "+", false)
)),
content
)
}
@ -239,7 +242,10 @@ pub trait TracksView: HasSize<TuiOut> + HasTrackScroll + HasSelection + HasMidiI
}
}))))));
Bsp::w(
self.view_track_header(theme, row!(Tui::bold(true, "[o]utput"), "[O] +")),
self.view_track_header(theme, row!(
Tui::bold(true, button_2("o", "utput", false)),
button_2("O", "+", false)
)),
content
)
}
@ -265,7 +271,10 @@ pub trait TracksView: HasSize<TuiOut> + HasTrackScroll + HasSelection + HasMidiI
}))));
Bsp::w(
self.view_track_header(theme, row!(Tui::bold(true, "[i]nputs"), "[I] +")),
self.view_track_header(theme, row!(
Tui::bold(true, button_2("i", "nputs", false)),
button_2("I", "+", false)
)),
Fixed::y(h, Fill::x(Align::w(Fixed::y(h + 1, content)))),
)
}
@ -275,7 +284,10 @@ pub trait TracksView: HasSize<TuiOut> + HasTrackScroll + HasSelection + HasMidiI
h = h.max(track.devices.len() as u16);
}
Bsp::w(
self.view_track_header(theme, row!(Tui::bold(true, "[d]evice "), "[D]+")),
self.view_track_header(theme, row!(
Tui::bold(true, button_2("d", "evice", false)),
button_2("D", "+", false)
)),
Fixed::y(h, Tui::bg(theme.darker.rgb, Align::w(Fill::x(Stack::east(
move|add: &mut dyn FnMut(&dyn Render<TuiOut>)|{
for (index, track, x1, x2) in self
@ -307,44 +319,40 @@ pub trait ScenesView: HasSelection + HasSceneScroll + Send + Sync {
fn width_side (&self) -> u16;
fn width_mid (&self) -> u16;
fn view_scenes_names (&self) -> impl Content<TuiOut> {
let h = self.scenes_with_prev_color().last().map(|(_,_,_,h,_)|h as u16).unwrap_or(0);
Fixed::y(h, Map::new(move||self.scenes_with_prev_color(),
move|(s, scene, y1, y2, previous): SceneWith<'_, Option<ItemTheme>>, _|{
let height = (1 + y2 - y1) as u16;
let name = Some(scene.name.clone());
let content = Fill::x(Align::w(Tui::bold(true, Bsp::e("", name))));
let selected = self.scene_selected() == Some(s);
let neighbor = s > 0 && self.scene_selected() == Some(s - 1);
let is_last = self.scenes().len().saturating_sub(1) == s;
let theme = scene.color;
let fg = theme.lightest.rgb;
let bg = if selected { theme.light } else { theme.base }.rgb;
let hi = if let Some(previous) = previous {
if neighbor { previous.light.rgb } else { previous.base.rgb }
} else {
Reset
};
let lo = if is_last { Reset } else if selected {
theme.light.rgb
} else {
theme.base.rgb
};
Fill::x(map_south(y1 as u16, height, Fixed::y(height, Phat {
width: 0, height: 0, content, colors: [fg, bg, hi, lo]
})))
}))
Stack::south(move|add: &mut dyn FnMut(&dyn Render<TuiOut>)|{
for (index, scene) in self.scenes().iter().enumerate().skip(self.scene_scroll()) {
add(&Self::view_scene_name(index, scene));
}
})
}
fn scenes_names_2 (&self, theme: ItemTheme) -> impl Content<TuiOut> {
let h = self.scenes().len() as u16 * 2;
let bg = theme.darker.rgb;
Fixed::y(h, Tui::bg(bg, Align::w(Fill::x(Map::new(
||self.scenes().iter().skip(self.scene_scroll()),
move|scene: &Scene, index|
Push::y(index as u16 * 2u16, Fixed::xy(20, 2,
Tui::bg(scene.color.dark.rgb, Align::nw(Bsp::e(
format!(" {index:2} "),
Tui::fg(Rgb(255, 255, 255),
Tui::bold(true, format!("{}", scene.name)))))))))))))
fn view_scene_name (index: usize, scene: &Scene) -> impl Content<TuiOut> {
Fixed::xy(20, 2, Tui::bg(scene.color.dark.rgb, Align::nw(Bsp::e(
format!(" {index:2} "),
Tui::fg(Rgb(255, 255, 255),
Tui::bold(true, format!("{}", scene.name)))))))
//let height = (1 + y2 - y1) as u16;
//let name = Some(scene.name.clone());
//let content = Fill::x(Align::w(Tui::bold(true, Bsp::e(" ⯈ ", name))));
//let selected = self.scene_selected() == Some(s);
//let neighbor = s > 0 && self.scene_selected() == Some(s - 1);
//let is_last = self.scenes().len().saturating_sub(1) == s;
//let theme = scene.color;
//let fg = theme.lightest.rgb;
//let bg = if selected { theme.light } else { theme.base }.rgb;
//let hi = if let Some(previous) = previous {
//if neighbor { previous.light.rgb } else { previous.base.rgb }
//} else {
//Reset
//};
//let lo = if is_last { Reset } else if selected {
//theme.light.rgb
//} else {
//theme.base.rgb
//};
//add(&Fill::x(map_south(y1 as u16, height, Fixed::y(height, Phat {
//width: 0, height: 0, content, colors: [fg, bg, hi, lo]
//}))))
//}
}
fn scenes_with_prev_color (&self) -> impl Iterator<Item=SceneWith<Option<ItemTheme>>> + Send + Sync {
self.scenes_iter().map(|(s, scene, y1, y2)|(s, scene, y1, y2,
@ -392,45 +400,80 @@ pub trait ClipsView: TracksView + ScenesView + Send + Sync {
fn view_scenes_clips <'a> (&'a self, editor: &'a Option<MidiEditor>)
-> impl Content<TuiOut> + 'a
{
let is_editing = false; //FIXME
let h = self.scenes_with_prev_color().last().map(|(_,_,_,h,_)|h as u16).unwrap_or(0);
Fixed::y(h, Self::per_track(||self.tracks_with_sizes_scrolled(),
move|track_index, track|Map::new(move||self.scenes_with_clip(track_index),
move|(s, scene, y1, y2, previous): SceneWith<'_, Option<ItemTheme>>, _|{
let (name, theme) = if let Some(clip) = &scene.clips[track_index] {
let clip = clip.read().unwrap();
(Some(clip.name.clone()), clip.color)
} else {
(None, ItemTheme::G[32])
};
let content = Fill::x(Align::w(Tui::bold(true, Bsp::e("", name))));
let same_track = self.track_selected() == Some(track_index);
let selected = same_track && self.scene_selected() == Some(s);
let neighbor = same_track && s > 0 && self.scene_selected() == Some(s - 1);
let is_last = self.scenes().len().saturating_sub(1) == s;
let fg = theme.lightest.rgb;
let bg = if selected { theme.light } else { theme.base }.rgb;
let hi = if let Some(previous) = previous {
if neighbor { previous.light.rgb } else { previous.base.rgb }
} else {
Reset
};
let lo = if is_last {
Reset
} else if selected {
theme.light.rgb
} else {
theme.base.rgb
};
let height = (1 + y2 - y1) as u16;
map_south(y1 as u16, height, Bsp::b(Fixed::y(height, Phat {
width: 0, height: 0, content, colors: [fg, bg, hi, lo]
}), When(
is_editing && same_track && self.scene_selected() == Some(s),
editor
)))
})))
Fill::xy(Stack::<TuiOut, _>::east(move|column: &mut dyn FnMut(&dyn Render<TuiOut>)|{
for (track_index, track, _, _) in self
.tracks_with_sizes(&self.selection(), None)
.skip(self.track_scroll())
{
//column(&Fixed::x(5, Fill::xy(Tui::bg(Green, "kyp"))));
column(&Fixed::x(
track.width as u16,
Fill::y(self.view_track_clips(track_index, track))
))
}
}))
}
fn view_track_clips <'a> (&'a self, track_index: usize, track: &Track) -> impl Content<TuiOut> {
Stack::south(move|cell: &mut dyn FnMut(&dyn Render<TuiOut>)|{
for (scene_index, scene) in self.scenes().iter().enumerate().skip(self.scene_scroll()) {
let (name, theme) = if let Some(Some(clip)) = &scene.clips.get(track_index) {
let clip = clip.read().unwrap();
(Some(clip.name.clone()), clip.color)
} else {
(None, ItemTheme::G[32])
};
let fg = theme.lightest.rgb;
let bg = if self.selection().track() == Some(track_index)
&& self.selection().scene() == Some(scene_index)
{
theme.light.rgb
} else if self.selection().track() == Some(track_index)
|| self.selection().scene() == Some(scene_index)
{
theme.base.rgb
} else {
theme.dark.rgb
};
cell(&Fixed::xy(track.width as u16, 2, Tui::fg_bg(fg, bg, Align::nw(name.unwrap_or(" ---- ".into())))));
//let (name, theme) = if let Some(clip) = &scene.clips.get(track_index).flatten() {
//let clip = clip.read().unwrap();
//(Some(clip.name.clone()), clip.color)
//} else {
//(None, ItemTheme::G[32])
//};
//let content = Fill::x(Align::w(Tui::bold(true, Bsp::e(" ⏹ ", name))));
//let same_track = self.track_selected() == Some(track_index);
//let selected = same_track && self.scene_selected() == Some(s);
//let neighbor = same_track && s > 0 && self.scene_selected() == Some(s - 1);
//let is_last = self.scenes().len().saturating_sub(1) == s;
//let fg = theme.lightest.rgb;
//let bg = if selected { theme.light } else { theme.base }.rgb;
//let hi = if let Some(previous) = previous {
//if neighbor { previous.light.rgb } else { previous.base.rgb }
//} else {
//Reset
//};
//let lo = if is_last {
//Reset
//} else if selected {
//theme.light.rgb
//} else {
//theme.base.rgb
//};
//let height = (1 + y2 - y1) as u16;
//let is_editing = false; //FIXME
//let editor = (); //FIXME
//cell(&Fixed::xy(track.width as u16, 2, Bsp::b(Fixed::y(height, Phat {
//width: 0, height: 0, content, colors: [fg, bg, hi, lo]
//}), When(
//is_editing && same_track && self.scene_selected() == Some(s),
//editor
//))))
}
})
}
fn scenes_clips_2 <'a> (
&'a self,
theme: ItemTheme