mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 19:56:42 +01:00
fix setting colors
This commit is contained in:
parent
a16e5361d1
commit
0999c42f12
10 changed files with 93 additions and 48 deletions
|
|
@ -86,7 +86,7 @@ macro_rules! transform_xy_unit {
|
|||
let u = iter.next().expect("no unit specified");
|
||||
let c = iter.next().expect("no content specified");
|
||||
let u = state.get(&u.value).expect("no unit provided");
|
||||
let c = state.get_content(&c.value).expect("not content provided");
|
||||
let c = state.get_content(&c.value).expect("no content provided");
|
||||
return Some(match k {
|
||||
$x => Self::x(u, c),
|
||||
$y => Self::y(u, c),
|
||||
|
|
@ -99,7 +99,7 @@ macro_rules! transform_xy_unit {
|
|||
let c = iter.next().expect("no content specified");
|
||||
let u = state.get(&u.value).expect("no unit provided");
|
||||
let v = state.get(&v.value).expect("no unit provided");
|
||||
let c = state.get_content(&c.value).expect("not content provided");
|
||||
let c = state.get_content(&c.value).expect("no content provided");
|
||||
return Some(Self::xy(u, v, c))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,9 +44,9 @@ pub struct TekCli {
|
|||
/// Multi-track MIDI sequencer.
|
||||
Arranger {
|
||||
/// Number of scenes
|
||||
#[arg(short = 'y', long, default_value_t = 1)] scenes: usize,
|
||||
#[arg(short = 'y', long, default_value_t = 12)] scenes: usize,
|
||||
/// Number of tracks
|
||||
#[arg(short = 'x', long, default_value_t = 1)] tracks: usize,
|
||||
#[arg(short = 'x', long, default_value_t = 16)] tracks: usize,
|
||||
/// Width of tracks
|
||||
#[arg(short = 'w', long, default_value_t = 12)] track_width: usize,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -55,7 +55,8 @@ atom_command!(TekCommand: |app: Tek| {
|
|||
("zoom" [z: usize] Some(Self::Zoom(z)))
|
||||
("edit" [] Some(Self::Edit(None)))
|
||||
("edit" [c: bool] Some(Self::Edit(c)))
|
||||
("color" [c: Color] Some(Self::Color(c.map(ItemPalette::from).unwrap_or_default())))
|
||||
("color" [c: Color] Some(Self::Color(ItemPalette::random())))
|
||||
("color" [c: Color] Some(Self::Color(c.map(ItemPalette::from).expect("no color"))))
|
||||
("enqueue" [c: Arc<RwLock<MidiClip>>] Some(Self::Enqueue(c)))
|
||||
("clip" [,..a] ClipCommand::try_from_expr(app, a).map(Self::Clip))
|
||||
("clock" [,..a] ClockCommand::try_from_expr(app.clock(), a).map(Self::Clock))
|
||||
|
|
@ -107,7 +108,7 @@ command!(|self: TekCommand, app: Tek|match self {
|
|||
let (index, mut clip) = pool.add_new_clip();
|
||||
// autocolor: new clip colors from scene and track color
|
||||
clip.write().unwrap().color = ItemColor::random_near(
|
||||
app.tracks[t.saturating_sub(1)].color.base.mix(
|
||||
app.tracks[t].color.base.mix(
|
||||
scene.color.base,
|
||||
0.5
|
||||
),
|
||||
|
|
@ -146,20 +147,16 @@ command!(|self: TekCommand, app: Tek|match self {
|
|||
old
|
||||
},
|
||||
Track(t) => {
|
||||
let t = t.saturating_sub(1);
|
||||
let old = app.tracks[t].color;
|
||||
app.tracks[t].color = palette;
|
||||
old
|
||||
}
|
||||
Scene(s) => {
|
||||
let s = s.saturating_sub(1);
|
||||
let old = app.scenes[s].color;
|
||||
app.scenes[s].color = palette;
|
||||
old
|
||||
}
|
||||
Clip(t, s) => {
|
||||
let t = t.saturating_sub(1);
|
||||
let s = s.saturating_sub(1);
|
||||
if let Some(ref clip) = app.scenes[s].clips[t] {
|
||||
let mut clip = clip.write().unwrap();
|
||||
let old = clip.color;
|
||||
|
|
@ -229,9 +226,9 @@ atom_command!(TrackCommand: |app: Tek| {
|
|||
("add" [] Some(Self::Add))
|
||||
("size" [a: usize] Some(Self::SetSize(a.unwrap())))
|
||||
("zoom" [a: usize] Some(Self::SetZoom(a.unwrap())))
|
||||
("color" [a: usize] Some(Self::SetColor(a.unwrap().saturating_sub(1), ItemPalette::random())))
|
||||
("del" [a: usize] Some(Self::Del(a.unwrap().saturating_sub(1))))
|
||||
("stop" [a: usize] Some(Self::Stop(a.unwrap().saturating_sub(1))))
|
||||
("color" [a: usize] Some(Self::SetColor(a.unwrap(), ItemPalette::random())))
|
||||
("del" [a: usize] Some(Self::Del(a.unwrap())))
|
||||
("stop" [a: usize] Some(Self::Stop(a.unwrap())))
|
||||
("swap" [a: usize, b: usize] Some(Self::Swap(a.unwrap(), b.unwrap())))
|
||||
("play" [] Some(Self::TogglePlay))
|
||||
("solo" [] Some(Self::ToggleSolo))
|
||||
|
|
@ -289,8 +286,8 @@ atom_command!(SceneCommand: |app: Tek| {
|
|||
("add" [] Some(Self::Add))
|
||||
("del" [a: usize] Some(Self::Del(0)))
|
||||
("zoom" [a: usize] Some(Self::SetZoom(a.unwrap())))
|
||||
("color" [a: usize] Some(Self::SetColor(a.unwrap().saturating_sub(1), ItemPalette::random())))
|
||||
("enqueue" [a: usize] Some(Self::Enqueue(a.unwrap().saturating_sub(1))))
|
||||
("color" [a: usize] Some(Self::SetColor(a.unwrap(), ItemPalette::G[128])))
|
||||
("enqueue" [a: usize] Some(Self::Enqueue(a.unwrap())))
|
||||
("swap" [a: usize, b: usize] Some(Self::Swap(a.unwrap(), b.unwrap())))
|
||||
});
|
||||
command!(|self: SceneCommand, app: Tek|match self {
|
||||
|
|
@ -327,12 +324,12 @@ command!(|self: SceneCommand, app: Tek|match self {
|
|||
SetColor(usize, usize, ItemPalette),
|
||||
}
|
||||
atom_command!(ClipCommand: |app: Tek| {
|
||||
("get" [a: usize ,b: usize] Some(Self::Get(a.unwrap().saturating_sub(1), b.unwrap().saturating_sub(1))))
|
||||
("put" [a: usize, b: usize, c: Option<Arc<RwLock<MidiClip>>>] Some(Self::Put(a.unwrap().saturating_sub(1), b.unwrap().saturating_sub(1), c.unwrap())))
|
||||
("enqueue" [a: usize, b: usize] Some(Self::Enqueue(a.unwrap().saturating_sub(1), b.unwrap().saturating_sub(1))))
|
||||
("get" [a: usize, b: usize] Some(Self::Get(a.unwrap(), b.unwrap())))
|
||||
("put" [a: usize, b: usize, c: Option<Arc<RwLock<MidiClip>>>] Some(Self::Put(a.unwrap(), b.unwrap(), c.unwrap())))
|
||||
("enqueue" [a: usize, b: usize] Some(Self::Enqueue(a.unwrap(), b.unwrap())))
|
||||
("edit" [a: Option<Arc<RwLock<MidiClip>>>] Some(Self::Edit(a.unwrap())))
|
||||
("loop" [a: usize, b: usize, c: bool] Some(Self::SetLoop(a.unwrap().saturating_sub(1), b.unwrap().saturating_sub(1), c.unwrap())))
|
||||
("color" [a: usize, b: usize] Some(Self::SetColor(a.unwrap().saturating_sub(1), b.unwrap().saturating_sub(1), ItemPalette::random())))
|
||||
("loop" [a: usize, b: usize, c: bool] Some(Self::SetLoop(a.unwrap(), b.unwrap(), c.unwrap())))
|
||||
("color" [a: usize, b: usize] Some(Self::SetColor(a.unwrap(), b.unwrap(), ItemPalette::random())))
|
||||
});
|
||||
command!(|self: ClipCommand, app: Tek|match self {
|
||||
Self::Get(track, scene) => { todo!() },
|
||||
|
|
@ -345,5 +342,14 @@ command!(|self: ClipCommand, app: Tek|match self {
|
|||
app.tracks[track].player.enqueue_next(app.scenes[scene].clips[track].as_ref());
|
||||
None
|
||||
},
|
||||
Self::SetColor(track, scene, color) => {
|
||||
app.scenes[scene].clips[track].as_ref().map(|clip|{
|
||||
let mut clip = clip.write().unwrap();
|
||||
let old = clip.color.clone();
|
||||
clip.color = color.clone();
|
||||
panic!("{color:?} {old:?}");
|
||||
Self::SetColor(track, scene, old)
|
||||
})
|
||||
},
|
||||
_ => None
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
(@q clip launch :track :scene)
|
||||
(@q clip enqueue :track :scene)
|
||||
(@c clip color :track :scene)
|
||||
(@g clip get)
|
||||
(@p clip put)
|
||||
|
|
|
|||
|
|
@ -20,8 +20,9 @@ view!(TuiOut: |self: Tek| self.size.of(View(self, self.view)); {
|
|||
":sampler" => ().boxed(),//self.view_sampler(self.is_editing(), &self.editor).boxed(),
|
||||
":scene-add" => self.view_scene_add().boxed(),
|
||||
":scenes" => self.view_scenes().boxed(),
|
||||
":status" => self.view_editor().boxed(),
|
||||
":toolbar" => self.view_clock().boxed(),
|
||||
":transport" => self.view_transport().boxed(),
|
||||
":status" => self.view_status().boxed(),
|
||||
":tracks" => self.view_tracks().boxed(),
|
||||
});
|
||||
provide_num!(u16: |self: Tek| {
|
||||
|
|
@ -50,8 +51,6 @@ impl Tek {
|
|||
pub(crate) fn w (&self) -> u16 { self.size.w() as u16 }
|
||||
pub(crate) fn h (&self) -> u16 { self.size.h() as u16 }
|
||||
pub(crate) fn w_sidebar (&self) -> u16 { self.w() / if self.is_editing() { 16 } else { 8 } as u16 }
|
||||
pub(crate) fn w_tracks_area (&self) -> u16 { self.w().saturating_sub(2 * self.w_sidebar()) }
|
||||
pub(crate) fn h_tracks_area (&self) -> u16 { self.h().saturating_sub(self.h_inputs() + self.h_outputs() + 10) }
|
||||
pub(crate) fn row <'a> (
|
||||
&'a self,
|
||||
w: u16,
|
||||
|
|
@ -77,10 +76,10 @@ impl Tek {
|
|||
c: impl Content<TuiOut> + 'a,
|
||||
) -> impl Content<TuiOut> + 'a {
|
||||
Fixed::y(h, Bsp::a(
|
||||
Fill::x(Align::n(Fixed::x(w, Align::x(Tui::bg(Green, b))))),
|
||||
Fill::x(Align::n(Fixed::x(w, Align::x(Tui::bg(Reset, b))))),
|
||||
Bsp::a(
|
||||
Fill::x(Align::nw(Fixed::x(self.w_sidebar() as u16, Tui::bg(Red, a)))),
|
||||
Fill::x(Align::ne(Fixed::x(self.w_sidebar() as u16, Tui::bg(Yellow, c)))),
|
||||
Fill::x(Align::nw(Fixed::x(self.w_sidebar() as u16, Tui::bg(Reset, a)))),
|
||||
Fill::x(Align::ne(Fixed::x(self.w_sidebar() as u16, Tui::bg(Reset, c)))),
|
||||
),
|
||||
))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
(bsp/n
|
||||
(fixed/y 2 :toolbar)
|
||||
(fill/xy (bsp/a
|
||||
(fill/xy (align/e :pool))
|
||||
(bsp/s :inputs (bsp/s :tracks (bsp/n :outputs :scenes))))))
|
||||
(bsp/n (fixed/y 1 :transport)
|
||||
(bsp/s (fixed/y 1 :status)
|
||||
(fill/xy (bsp/a (fill/xy (align/e :pool))
|
||||
(bsp/s :inputs (bsp/s :tracks (bsp/n :outputs :scenes)))))))
|
||||
|
|
|
|||
|
|
@ -46,6 +46,32 @@ impl Tek {
|
|||
)))
|
||||
)
|
||||
}
|
||||
pub(crate) fn view_status (&self) -> impl Content<TuiOut> + use<'_> {
|
||||
self.update_clock();
|
||||
let theme = ItemPalette::G[96];
|
||||
let fmtd = self.fmtd.read().unwrap();
|
||||
Tui::bg(Black, row!(Bsp::a(
|
||||
Fill::xy(Align::w(self.view_play_pause())),
|
||||
Fill::xy(Align::e(row!(
|
||||
FieldH(theme, "BPM", fmtd.bpm.view.clone()),
|
||||
FieldH(theme, "Beat", fmtd.beat.view.clone()),
|
||||
FieldH(theme, "Time", fmtd.time.view.clone())
|
||||
)))
|
||||
)))
|
||||
}
|
||||
pub(crate) fn view_transport (&self) -> impl Content<TuiOut> + use<'_> {
|
||||
self.update_clock();
|
||||
let theme = ItemPalette::G[96];
|
||||
let fmtd = self.fmtd.read().unwrap();
|
||||
Tui::bg(Black, row!(Bsp::a(
|
||||
Fill::xy(Align::w(FieldH(theme, "Sel", self.selected.describe(&self.tracks, &self.scenes)))),
|
||||
Fill::xy(Align::e(row!(
|
||||
FieldH(theme, "SR", fmtd.sr.view.clone()),
|
||||
FieldH(theme, "Buf", fmtd.buf.view.clone()),
|
||||
FieldH(theme, "Lat", fmtd.lat.view.clone()),
|
||||
)))
|
||||
)))
|
||||
}
|
||||
fn view_play_pause (&self) -> impl Content<TuiOut> + use<'_> {
|
||||
let playing = self.clock.is_rolling();
|
||||
let compact = true;//self.is_editing();
|
||||
|
|
|
|||
|
|
@ -1,15 +1,18 @@
|
|||
use crate::*;
|
||||
impl Tek {
|
||||
const H_SCENE: usize = 2;
|
||||
const H_EDITOR: usize = 15;
|
||||
pub(crate) fn h_scenes (&self, editing: bool, height: usize, larger: usize) -> u16 {
|
||||
self.scenes_sizes(editing, height, larger).last().map(|(_, _, _, y)|y as u16).unwrap_or(0)}
|
||||
self.scenes_sizes(editing, height, larger).last().map(|(_, _, _, y)|y as u16).unwrap_or(0)
|
||||
}
|
||||
pub(crate) fn scenes_sizes (&self, editing: bool, height: usize, larger: usize) -> impl ScenesSizes<'_> {
|
||||
let mut y = 0;
|
||||
let (selected_track, selected_scene) = match self.selected() {
|
||||
Selection::Track(t) => (Some(*t), None),
|
||||
Selection::Scene(s) => (None, Some(*s)),
|
||||
Selection::Clip(t, s) => (Some(*t), Some(*s)),
|
||||
_ => (None, None)
|
||||
};
|
||||
let mut y = 0;
|
||||
self.scenes().iter().enumerate().map(move|(s, scene)|{
|
||||
let active = editing && selected_track.is_some() && selected_scene == Some(s);
|
||||
let height = if active { larger } else { height };
|
||||
|
|
@ -19,22 +22,24 @@ impl Tek {
|
|||
pub fn view_scenes (&self) -> impl Content<TuiOut> + use<'_> {
|
||||
let w_full = self.w();
|
||||
let w = self.w_tracks_area();
|
||||
let h = self.h_tracks_area();
|
||||
let h_area = self.h_tracks_area();
|
||||
let editing = self.is_editing();
|
||||
let selected_track = self.selected().track();
|
||||
let selected_scene = self.selected().scene();
|
||||
let h = self.h_scenes(editing, Self::H_SCENE, Self::H_EDITOR);
|
||||
let scene_names = Map::new(
|
||||
move||self.scenes_with_colors(editing, h),
|
||||
move||self.scenes_with_colors(editing, h_area),
|
||||
move|(s, scene, y1, y2, prev): SceneColor, _|self.view_scene_name(
|
||||
w_full, (1 + y2 - y1) as u16, y1 as u16, s, scene, prev));
|
||||
let scene_clips = self.per_track(move|t, track|Map::new(
|
||||
move||self.scenes_with_track_colors(editing, h, t),
|
||||
move||self.scenes_with_track_colors(editing, h_area, t),
|
||||
move|(s, scene, y1, y2, prev): SceneColor, _|self.view_scene_clip(
|
||||
w, (1 + y2 - y1) as u16, y1 as u16,
|
||||
scene, prev, s, t, editing, selected_track == Some(t), selected_scene)));
|
||||
Tui::bg(Black, self.row_top(self.w_tracks_area(), h, scene_names, scene_clips, ())) }
|
||||
Tui::bg(Reset, Fixed::y(self.h_tracks_area(),
|
||||
self.row(self.w_tracks_area(), h, scene_names, scene_clips, ()))) }
|
||||
fn scenes_with_colors (&self, editing: bool, h: u16) -> impl ScenesColors<'_> {
|
||||
self.scenes_sizes(editing, 2, 15).map_while(
|
||||
self.scenes_sizes(editing, Self::H_SCENE, Self::H_EDITOR).map_while(
|
||||
move|(s, scene, y1, y2)|if y2 as u16 > h {
|
||||
None
|
||||
} else { Some((s, scene, y1, y2, if s == 0 {
|
||||
|
|
@ -50,9 +55,9 @@ impl Tek {
|
|||
let fg = scene.color.lightest.rgb;
|
||||
let name = Some(scene.name.clone());
|
||||
let cell = self.view_scene_cell(true, s, &bg, prev, name, " ⯈ ", fg);
|
||||
map_south(offset, height, Fixed::y(height, cell)) }
|
||||
Fill::x(map_south(offset, height, Fixed::y(height, cell))) }
|
||||
fn scenes_with_track_colors (&self, editing: bool, h: u16, t: usize) -> impl ScenesColors<'_> {
|
||||
self.scenes_sizes(editing, 2, 15).map_while(
|
||||
self.scenes_sizes(editing, Self::H_SCENE, Self::H_EDITOR).map_while(
|
||||
move|(s, scene, y1, y2)|if y2 as u16 > h {
|
||||
None
|
||||
} else { Some((s, scene, y1, y2, if s == 0 {
|
||||
|
|
@ -92,8 +97,12 @@ impl Tek {
|
|||
let neighbor = same_track && scene > 0 && selected_scene == Some(scene - 1);
|
||||
let is_last = scene == self.scenes.len().saturating_sub(1);
|
||||
let colors = Self::colors(color, prev, selected, neighbor, is_last);
|
||||
let content = Fill::x(Align::w(Tui::fg(fg, Tui::bold(true, Bsp::e(icon, name)))));
|
||||
Phat { width: 0, height: 0, selected, content, colors, } }
|
||||
Self::cell(icon, name, colors) }
|
||||
fn cell <'a> (
|
||||
icon: &'a str, name: Option<Arc<str>>, colors: [Color;4]
|
||||
) -> impl Content<TuiOut> + use<'a> {
|
||||
let content = Fill::x(Align::w(Tui::bold(true, Bsp::e(icon, name))));
|
||||
Phat { width: 0, height: 0, content, colors, } }
|
||||
const TAB: &str = " Tab";
|
||||
pub fn view_scene_add (&self) -> impl Content<TuiOut> + use<'_> {
|
||||
let data = (self.selected().scene().unwrap_or(0), self.scenes().len());
|
||||
|
|
|
|||
|
|
@ -1,5 +1,15 @@
|
|||
use crate::*;
|
||||
impl Tek {
|
||||
pub(crate) fn w_tracks_area (&self) -> u16 {
|
||||
self.w().saturating_sub(2 * self.w_sidebar())
|
||||
}
|
||||
pub(crate) fn w_tracks (&self, editing: bool, bigger: usize) -> u16 {
|
||||
self.tracks_sizes(editing, bigger).last().map(|(_, _, _, x)|x as u16).unwrap_or(0)
|
||||
}
|
||||
pub(crate) fn h_tracks_area (&self) -> u16 {
|
||||
self.h().saturating_sub(self.h_inputs() + self.h_outputs() + 10)
|
||||
}
|
||||
|
||||
pub fn view_tracks (&self) -> impl Content<TuiOut> + use<'_> {
|
||||
let w = (self.size.w() as u16).saturating_sub(2 * self.w_sidebar());
|
||||
let data = (self.selected.track().unwrap_or(0), self.tracks().len());
|
||||
|
|
@ -27,15 +37,12 @@ impl Tek {
|
|||
let width = self.w_tracks_area();
|
||||
let filter = move|(t, track, x1, x2)|if x2 as u16 >= width {None} else {Some((t, track, x1, x2))};
|
||||
let tracks = move||self.tracks_sizes(self.is_editing(), self.editor_w()).map_while(filter);
|
||||
Align::x(Tui::bg(Green, Map::new(tracks, move|(index, track, x1, x2), _|{
|
||||
Align::x(Tui::bg(Reset, Map::new(tracks, move|(index, track, x1, x2), _|{
|
||||
let width = (x2 - x1) as u16;
|
||||
map_east(x1 as u16, width, Fixed::x(width, Tui::fg_bg(
|
||||
track.color.lightest.rgb,
|
||||
track.color.base.rgb,
|
||||
f(index, track)))) }))) }
|
||||
pub(crate) fn w_tracks (&self, editing: bool, bigger: usize) -> u16 {
|
||||
self.tracks_sizes(editing, bigger).last().map(|(_, _, _, x)|x as u16).unwrap_or(0)
|
||||
}
|
||||
fn tracks_sizes <'a> (&'a self, editing: bool, bigger: usize) -> impl TracksSizes<'a> {
|
||||
let mut x = 0;
|
||||
let active = match self.selected() {
|
||||
|
|
|
|||
|
|
@ -116,7 +116,6 @@ pub struct Phat<T> {
|
|||
pub height: u16,
|
||||
pub content: T,
|
||||
pub colors: [Color;4],
|
||||
pub selected: bool,
|
||||
}
|
||||
impl<T> Phat<T> {
|
||||
/// A phat line
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue