mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-08 20:56:43 +01:00
grid -> arranger
This commit is contained in:
parent
d99a08bcf7
commit
f1f812d0fb
5 changed files with 131 additions and 191 deletions
128
src/control.rs
128
src/control.rs
|
|
@ -15,8 +15,8 @@ handle!(App |self, e| {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
let handle_focused = |state: &mut Self|match state.section {
|
let handle_focused = |state: &mut Self|match state.section {
|
||||||
AppSection::Grid =>
|
AppSection::Arranger =>
|
||||||
handle_keymap(state, e, KEYMAP_GRID),
|
handle_keymap(state, e, KEYMAP_ARRANGER),
|
||||||
AppSection::Sequencer =>
|
AppSection::Sequencer =>
|
||||||
handle_keymap(state, e, KEYMAP_SEQUENCER),
|
handle_keymap(state, e, KEYMAP_SEQUENCER),
|
||||||
AppSection::Chain =>
|
AppSection::Chain =>
|
||||||
|
|
@ -47,7 +47,6 @@ const KEYMAP_FOCUS: &'static [KeyBinding<App>] = keymap!(App {
|
||||||
});
|
});
|
||||||
|
|
||||||
const KEYMAP: &'static [KeyBinding<App>] = keymap!(App {
|
const KEYMAP: &'static [KeyBinding<App>] = keymap!(App {
|
||||||
|
|
||||||
[F(1), NONE, "help_toggle", "toggle help", |_: &mut App| {Ok(true)}],
|
[F(1), NONE, "help_toggle", "toggle help", |_: &mut App| {Ok(true)}],
|
||||||
|
|
||||||
[Up, NONE, "focus_prev", "focus previous area", focus_prev],
|
[Up, NONE, "focus_prev", "focus previous area", focus_prev],
|
||||||
|
|
@ -140,24 +139,32 @@ const KEYMAP: &'static [KeyBinding<App>] = keymap!(App {
|
||||||
// [Char('s'), NONE, "stop_and_rewind", "Stop and rewind", stop_and_rewind],
|
// [Char('s'), NONE, "stop_and_rewind", "Stop and rewind", stop_and_rewind],
|
||||||
});
|
});
|
||||||
|
|
||||||
const KEYMAP_GRID: &'static [KeyBinding<App>] = keymap!(App {
|
const KEYMAP_ARRANGER: &'static [KeyBinding<App>] = keymap!(App {
|
||||||
[Up, NONE, "grid_cursor_up", "move cursor up", |app: &mut App| Ok(match app.grid_mode {
|
[Up, NONE, "arranger_cursor_up", "move cursor up", |app: &mut App| Ok(
|
||||||
false => {app.scene_cursor = app.scene_cursor.saturating_sub(1); true},
|
match app.arranger_mode {
|
||||||
true => {app.track_cursor = app.track_cursor.saturating_sub(1); true},
|
false => {app.scene_cursor = app.scene_cursor.saturating_sub(1); true},
|
||||||
})],
|
true => {app.track_cursor = app.track_cursor.saturating_sub(1); true},
|
||||||
[Down, NONE, "grid_cursor_down", "move cursor down", |app: &mut App| Ok(match app.grid_mode {
|
}
|
||||||
false => {app.scene_cursor = app.scenes.len().min(app.scene_cursor + 1); true},
|
)],
|
||||||
true => {app.track_cursor = app.tracks.len().min(app.track_cursor + 1); true},
|
[Down, NONE, "arranger_cursor_down", "move cursor down", |app: &mut App| Ok(
|
||||||
})],
|
match app.arranger_mode {
|
||||||
[Left, NONE, "grid_cursor_left", "move cursor left", |app: &mut App| Ok(match app.grid_mode {
|
false => {app.scene_cursor = app.scenes.len().min(app.scene_cursor + 1); true},
|
||||||
false => {app.track_cursor = app.track_cursor.saturating_sub(1); true},
|
true => {app.track_cursor = app.tracks.len().min(app.track_cursor + 1); true},
|
||||||
true => {app.scene_cursor = app.scene_cursor.saturating_sub(1); true},
|
}
|
||||||
})],
|
)],
|
||||||
[Right, NONE, "grid_cursor_right", "move cursor right", |app: &mut App| Ok(match app.grid_mode {
|
[Left, NONE, "arranger_cursor_left", "move cursor left", |app: &mut App| Ok(
|
||||||
false => {app.track_cursor = app.tracks.len().min(app.track_cursor + 1); true},
|
match app.arranger_mode {
|
||||||
true => {app.scene_cursor = app.scenes.len().min(app.scene_cursor + 1); true},
|
false => {app.track_cursor = app.track_cursor.saturating_sub(1); true},
|
||||||
})],
|
true => {app.scene_cursor = app.scene_cursor.saturating_sub(1); true},
|
||||||
[Enter, NONE, "grid_activate", "activate item at cursor", |app: &mut App| Ok(
|
}
|
||||||
|
)],
|
||||||
|
[Right, NONE, "arranger_cursor_right", "move cursor right", |app: &mut App| Ok(
|
||||||
|
match app.arranger_mode {
|
||||||
|
false => {app.track_cursor = app.tracks.len().min(app.track_cursor + 1); true},
|
||||||
|
true => {app.scene_cursor = app.scenes.len().min(app.scene_cursor + 1); true},
|
||||||
|
}
|
||||||
|
)],
|
||||||
|
[Enter, NONE, "arranger_activate", "activate item at cursor", |app: &mut App| Ok(
|
||||||
if app.scene_cursor == 0 {
|
if app.scene_cursor == 0 {
|
||||||
false
|
false
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -175,52 +182,43 @@ const KEYMAP_GRID: &'static [KeyBinding<App>] = keymap!(App {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
)],
|
)],
|
||||||
[Char('.'), NONE, "grid_increment", "set next clip at cursor", |app: &mut App| {
|
[Char('.'), NONE, "arranger_increment", "set next clip at cursor", |app: &mut App| {
|
||||||
|
//if state.cursor.0 >= 1 && state.cursor.1 >= 1 {
|
||||||
|
//let scene_id = state.cursor.1 - 1;
|
||||||
|
//let clip_id = state.cursor.0 - 1;
|
||||||
|
//let scene = &mut state.scenes[scene_id];
|
||||||
|
//scene.clips[clip_id] = match scene.clips[clip_id] {
|
||||||
|
//None => Some(0),
|
||||||
|
//Some(i) => if i >= state.tracks[clip_id].sequencer.phrases.len().saturating_sub(1) {
|
||||||
|
//None
|
||||||
|
//} else {
|
||||||
|
//Some(i + 1)
|
||||||
|
//}
|
||||||
|
//};
|
||||||
|
//}
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}],
|
}],
|
||||||
[Char(','), NONE, "grid_decrement", "set previous clip at cursor", |app: &mut App| {
|
[Char(','), NONE, "arranger_decrement", "set previous clip at cursor", |app: &mut App| {
|
||||||
|
//if state.cursor.0 >= 1 && state.cursor.1 >= 1 {
|
||||||
|
//let scene_id = state.cursor.1 - 1;
|
||||||
|
//let clip_id = state.cursor.0 - 1;
|
||||||
|
//let scene = &mut state.scenes[scene_id];
|
||||||
|
//scene.clips[clip_id] = match scene.clips[clip_id] {
|
||||||
|
//None => Some(state.tracks[clip_id].sequencer.phrases.len().saturating_sub(1)),
|
||||||
|
//Some(i) => if i == 0 {
|
||||||
|
//None
|
||||||
|
//} else {
|
||||||
|
//Some(i - 1)
|
||||||
|
//}
|
||||||
|
//};
|
||||||
|
//}
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}],
|
}],
|
||||||
[Char('`'), NONE, "grid_mode_switch", "switch the display mode", |app: &mut App| {
|
[Char('`'), NONE, "arranger_mode_switch", "switch the display mode", |app: &mut App| {
|
||||||
app.grid_mode = !app.seq_mode;
|
app.arranger_mode = !app.seq_mode;
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}],
|
}],
|
||||||
});
|
});
|
||||||
fn clip_next (_: &mut App) -> Usually<bool> { Ok(true) }
|
|
||||||
//fn clip_next (state: &mut Launcher) -> Usually<bool> {
|
|
||||||
//if state.cursor.0 >= 1 && state.cursor.1 >= 1 {
|
|
||||||
//let scene_id = state.cursor.1 - 1;
|
|
||||||
//let clip_id = state.cursor.0 - 1;
|
|
||||||
//let scene = &mut state.scenes[scene_id];
|
|
||||||
//scene.clips[clip_id] = match scene.clips[clip_id] {
|
|
||||||
//None => Some(0),
|
|
||||||
//Some(i) => if i >= state.tracks[clip_id].sequencer.phrases.len().saturating_sub(1) {
|
|
||||||
//None
|
|
||||||
//} else {
|
|
||||||
//Some(i + 1)
|
|
||||||
//}
|
|
||||||
//};
|
|
||||||
//}
|
|
||||||
//Ok(true)
|
|
||||||
//}
|
|
||||||
|
|
||||||
fn clip_prev (_: &mut App) -> Usually<bool> { Ok(true) }
|
|
||||||
//fn clip_prev (state: &mut Launcher) -> Usually<bool> {
|
|
||||||
//if state.cursor.0 >= 1 && state.cursor.1 >= 1 {
|
|
||||||
//let scene_id = state.cursor.1 - 1;
|
|
||||||
//let clip_id = state.cursor.0 - 1;
|
|
||||||
//let scene = &mut state.scenes[scene_id];
|
|
||||||
//scene.clips[clip_id] = match scene.clips[clip_id] {
|
|
||||||
//None => Some(state.tracks[clip_id].sequencer.phrases.len().saturating_sub(1)),
|
|
||||||
//Some(i) => if i == 0 {
|
|
||||||
//None
|
|
||||||
//} else {
|
|
||||||
//Some(i - 1)
|
|
||||||
//}
|
|
||||||
//};
|
|
||||||
//}
|
|
||||||
//Ok(true)
|
|
||||||
//}
|
|
||||||
|
|
||||||
const KEYMAP_SEQUENCER: &'static [KeyBinding<App>] = keymap!(App {
|
const KEYMAP_SEQUENCER: &'static [KeyBinding<App>] = keymap!(App {
|
||||||
[Up, NONE, "seq_cursor_up", "move cursor up", |app: &mut App| {
|
[Up, NONE, "seq_cursor_up", "move cursor up", |app: &mut App| {
|
||||||
|
|
@ -258,8 +256,12 @@ const KEYMAP_SEQUENCER: &'static [KeyBinding<App>] = keymap!(App {
|
||||||
});
|
});
|
||||||
|
|
||||||
const KEYMAP_CHAIN: &'static [KeyBinding<App>] = keymap!(App {
|
const KEYMAP_CHAIN: &'static [KeyBinding<App>] = keymap!(App {
|
||||||
[Up, NONE, "chain_cursor_up", "move cursor up", |_: &mut App| Ok(true)],
|
[Up, NONE, "chain_cursor_up", "move cursor up", |_: &mut App| {
|
||||||
[Down, NONE, "chain_cursor_down", "move cursor down", |_: &mut App| Ok(true)],
|
Ok(true)
|
||||||
|
}],
|
||||||
|
[Down, NONE, "chain_cursor_down", "move cursor down", |_: &mut App| {
|
||||||
|
Ok(true)
|
||||||
|
}],
|
||||||
[Left, NONE, "chain_cursor_left", "move cursor left", |app: &mut App| {
|
[Left, NONE, "chain_cursor_left", "move cursor left", |app: &mut App| {
|
||||||
if let Some((_, track)) = app.track_mut() {
|
if let Some((_, track)) = app.track_mut() {
|
||||||
track.device = track.device.saturating_sub(1);
|
track.device = track.device.saturating_sub(1);
|
||||||
|
|
@ -303,7 +305,7 @@ fn decrement (app: &mut App) -> Usually<bool> {
|
||||||
|
|
||||||
fn delete (app: &mut App) -> Usually<bool> {
|
fn delete (app: &mut App) -> Usually<bool> {
|
||||||
match app.section {
|
match app.section {
|
||||||
AppSection::Grid => delete_track(app),
|
AppSection::Arranger => delete_track(app),
|
||||||
_ => Ok(false)
|
_ => Ok(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
72
src/model.rs
72
src/model.rs
|
|
@ -18,59 +18,59 @@ use crate::core::*;
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct App {
|
pub struct App {
|
||||||
/// Paths to user directories
|
/// Paths to user directories
|
||||||
pub xdg: Option<Arc<XdgApp>>,
|
pub xdg: Option<Arc<XdgApp>>,
|
||||||
/// Main JACK client.
|
/// Main JACK client.
|
||||||
pub jack: Option<DynamicAsyncClient>,
|
pub jack: Option<DynamicAsyncClient>,
|
||||||
/// Main MIDI controller.
|
/// Main MIDI controller.
|
||||||
pub midi_in: Option<Port<MidiIn>>,
|
pub midi_in: Option<Port<MidiIn>>,
|
||||||
/// Main audio outputs.
|
/// Main audio outputs.
|
||||||
pub audio_outs: Vec<Arc<Port<Unowned>>>,
|
pub audio_outs: Vec<Arc<Port<Unowned>>>,
|
||||||
/// JACK transport handle.
|
/// JACK transport handle.
|
||||||
pub transport: Option<Transport>,
|
pub transport: Option<Transport>,
|
||||||
/// Current transport state
|
/// Current transport state
|
||||||
pub playing: Option<TransportState>,
|
pub playing: Option<TransportState>,
|
||||||
/// Current position according to transport
|
/// Current position according to transport
|
||||||
pub playhead: usize,
|
pub playhead: usize,
|
||||||
/// Position of T0 for this playback within global timeline
|
/// Position of T0 for this playback within global timeline
|
||||||
pub play_started: Option<(usize, usize)>,
|
pub play_started: Option<(usize, usize)>,
|
||||||
/// Current sample rate and tempo.
|
/// Current sample rate and tempo.
|
||||||
pub timebase: Arc<Timebase>,
|
pub timebase: Arc<Timebase>,
|
||||||
/// Display mode of grid section
|
/// Display mode of arranger section
|
||||||
pub grid_mode: bool,
|
pub arranger_mode: bool,
|
||||||
/// Display mode of chain section
|
/// Display mode of chain section
|
||||||
pub chain_mode: bool,
|
pub chain_mode: bool,
|
||||||
/// Display mode of sequencer seciton
|
/// Display mode of sequencer seciton
|
||||||
pub seq_mode: bool,
|
pub seq_mode: bool,
|
||||||
/// Optional modal dialog
|
/// Optional modal dialog
|
||||||
pub modal: Option<Box<dyn Component>>,
|
pub modal: Option<Box<dyn Component>>,
|
||||||
/// Currently focused section
|
/// Currently focused section
|
||||||
pub section: AppSection,
|
pub section: AppSection,
|
||||||
/// Whether the section is focused
|
/// Whether the section is focused
|
||||||
pub entered: bool,
|
pub entered: bool,
|
||||||
/// Current frame
|
/// Current frame
|
||||||
pub metronome: bool,
|
pub metronome: bool,
|
||||||
/// Display position of cursor within note range
|
/// Display position of cursor within note range
|
||||||
pub note_cursor: usize,
|
pub note_cursor: usize,
|
||||||
/// Range of notes to display
|
/// Range of notes to display
|
||||||
pub note_start: usize,
|
pub note_start: usize,
|
||||||
/// Display position of cursor within time range
|
/// Display position of cursor within time range
|
||||||
pub time_cursor: usize,
|
pub time_cursor: usize,
|
||||||
/// PPQ per display unit
|
/// PPQ per display unit
|
||||||
pub time_zoom: usize,
|
pub time_zoom: usize,
|
||||||
/// Range of time steps to display
|
/// Range of time steps to display
|
||||||
pub time_start: usize,
|
pub time_start: usize,
|
||||||
/// Focused scene+1, 0 is track list
|
/// Focused scene+1, 0 is track list
|
||||||
pub scene_cursor: usize,
|
pub scene_cursor: usize,
|
||||||
/// Collection of scenes
|
/// Collection of scenes
|
||||||
pub scenes: Vec<Scene>,
|
pub scenes: Vec<Scene>,
|
||||||
/// Focused track+1, 0 is scene list
|
/// Focused track+1, 0 is scene list
|
||||||
pub track_cursor: usize,
|
pub track_cursor: usize,
|
||||||
/// Collection of tracks
|
/// Collection of tracks
|
||||||
pub tracks: Vec<Track>,
|
pub tracks: Vec<Track>,
|
||||||
|
/// Number of frames requested by process callback
|
||||||
pub chunk_size: usize,
|
pub chunk_size: usize,
|
||||||
|
/// Quantization factor
|
||||||
pub quant: usize,
|
pub quant: usize,
|
||||||
}
|
}
|
||||||
process!(App |self, _client, scope| {
|
process!(App |self, _client, scope| {
|
||||||
let (
|
let (
|
||||||
|
|
@ -299,28 +299,28 @@ struct SelectionMut<'a> {
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Copy)]
|
#[derive(PartialEq, Clone, Copy)]
|
||||||
pub enum AppSection {
|
pub enum AppSection {
|
||||||
Grid,
|
Arranger,
|
||||||
Sequencer,
|
Sequencer,
|
||||||
Chain,
|
Chain,
|
||||||
}
|
}
|
||||||
impl Default for AppSection {
|
impl Default for AppSection {
|
||||||
fn default () -> Self {
|
fn default () -> Self {
|
||||||
Self::Grid
|
Self::Arranger
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl AppSection {
|
impl AppSection {
|
||||||
pub fn prev (&mut self) {
|
pub fn prev (&mut self) {
|
||||||
*self = match self {
|
*self = match self {
|
||||||
Self::Grid => Self::Chain,
|
Self::Arranger => Self::Chain,
|
||||||
Self::Sequencer => Self::Grid,
|
Self::Sequencer => Self::Arranger,
|
||||||
Self::Chain => Self::Sequencer,
|
Self::Chain => Self::Sequencer,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn next (&mut self) {
|
pub fn next (&mut self) {
|
||||||
*self = match self {
|
*self = match self {
|
||||||
Self::Grid => Self::Sequencer,
|
Self::Arranger => Self::Sequencer,
|
||||||
Self::Sequencer => Self::Chain,
|
Self::Sequencer => Self::Chain,
|
||||||
Self::Chain => Self::Grid,
|
Self::Chain => Self::Arranger,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
32
src/view.rs
32
src/view.rs
|
|
@ -1,18 +1,16 @@
|
||||||
pub mod chain;
|
pub mod chain;
|
||||||
pub mod grid;
|
pub mod arranger;
|
||||||
pub mod layout;
|
pub mod layout;
|
||||||
pub mod sampler;
|
pub mod sampler;
|
||||||
pub mod sequencer;
|
pub mod sequencer;
|
||||||
pub mod transport;
|
pub mod transport;
|
||||||
pub mod plugin;
|
pub mod plugin;
|
||||||
pub mod focus;
|
|
||||||
pub mod border;
|
pub mod border;
|
||||||
|
|
||||||
pub use self::border::*;
|
pub use self::border::*;
|
||||||
pub use self::layout::*;
|
pub use self::layout::*;
|
||||||
pub use self::transport::TransportView;
|
pub use self::transport::TransportView;
|
||||||
pub use self::grid::*;
|
pub use self::arranger::*;
|
||||||
pub use self::focus::*;
|
|
||||||
pub use self::chain::ChainView;
|
pub use self::chain::ChainView;
|
||||||
pub use self::sequencer::SequencerView;
|
pub use self::sequencer::SequencerView;
|
||||||
|
|
||||||
|
|
@ -22,23 +20,23 @@ render!(App |self, buf, area| {
|
||||||
let Rect { x, y, width, height } = area;
|
let Rect { x, y, width, height } = area;
|
||||||
let transport = self.draw_transport(buf, area)?;
|
let transport = self.draw_transport(buf, area)?;
|
||||||
let y = y + transport.height;
|
let y = y + transport.height;
|
||||||
let grid = if self.grid_mode {
|
let arranger = if self.arranger_mode {
|
||||||
self.draw_grid_horizontal(buf, Rect {
|
self.draw_arranger_horizontal(buf, Rect {
|
||||||
x, y, width, height: height / 3
|
x, y, width, height: height / 3
|
||||||
})?
|
})?
|
||||||
} else {
|
} else {
|
||||||
self.draw_grid_vertical(buf, Rect {
|
self.draw_arranger_vertical(buf, Rect {
|
||||||
x, y, width, height: height / 3
|
x, y, width, height: height / 3
|
||||||
})?
|
})?
|
||||||
};
|
};
|
||||||
if self.section == AppSection::Grid {
|
if self.section == AppSection::Arranger {
|
||||||
QuarterV(if self.entered {
|
QuarterV(if self.entered {
|
||||||
Style::default().green()
|
Style::default().green()
|
||||||
} else {
|
} else {
|
||||||
Style::default().green().dim()
|
Style::default().green().dim()
|
||||||
}).draw(buf, grid)
|
}).draw(buf, arranger)
|
||||||
}
|
}
|
||||||
let y = y + grid.height;
|
let y = y + arranger.height;
|
||||||
if self.track_cursor > 0 {
|
if self.track_cursor > 0 {
|
||||||
let chain = self.draw_chain(buf, Rect {
|
let chain = self.draw_chain(buf, Rect {
|
||||||
x, y: y + height - height / 3 - 1, width, height: height / 3
|
x, y: y + height - height / 3 - 1, width, height: height / 3
|
||||||
|
|
@ -48,7 +46,7 @@ render!(App |self, buf, area| {
|
||||||
Style::default().green()
|
Style::default().green()
|
||||||
} else {
|
} else {
|
||||||
Style::default().green().dim()
|
Style::default().green().dim()
|
||||||
}).draw(buf, chain)
|
}).draw(buf, Rect { width, ..chain })
|
||||||
}
|
}
|
||||||
let phrase = self.draw_phrase(buf, Rect {
|
let phrase = self.draw_phrase(buf, Rect {
|
||||||
x, y, width, height: height - height / 3
|
x, y, width, height: height - height / 3
|
||||||
|
|
@ -101,22 +99,22 @@ impl App {
|
||||||
quant: self.quant,
|
quant: self.quant,
|
||||||
}.render(buf, area)
|
}.render(buf, area)
|
||||||
}
|
}
|
||||||
fn draw_grid_horizontal (&self, buf: &mut Buffer, area: Rect) -> Usually<Rect> {
|
fn draw_arranger_horizontal (&self, buf: &mut Buffer, area: Rect) -> Usually<Rect> {
|
||||||
SceneGridViewHorizontal {
|
ArrangerViewHorizontal {
|
||||||
buf,
|
buf,
|
||||||
area,
|
area,
|
||||||
focused: self.section == AppSection::Grid,
|
focused: self.section == AppSection::Arranger,
|
||||||
entered: self.entered,
|
entered: self.entered,
|
||||||
scenes: &self.scenes,
|
scenes: &self.scenes,
|
||||||
tracks: &self.tracks,
|
tracks: &self.tracks,
|
||||||
cursor: &(self.track_cursor, self.scene_cursor),
|
cursor: &(self.track_cursor, self.scene_cursor),
|
||||||
}.draw()
|
}.draw()
|
||||||
}
|
}
|
||||||
fn draw_grid_vertical (&self, buf: &mut Buffer, area: Rect) -> Usually<Rect> {
|
fn draw_arranger_vertical (&self, buf: &mut Buffer, area: Rect) -> Usually<Rect> {
|
||||||
SceneGridViewVertical {
|
ArrangerViewVertical {
|
||||||
buf,
|
buf,
|
||||||
area,
|
area,
|
||||||
focused: self.section == AppSection::Grid,
|
focused: self.section == AppSection::Arranger,
|
||||||
entered: self.entered,
|
entered: self.entered,
|
||||||
scenes: &self.scenes,
|
scenes: &self.scenes,
|
||||||
tracks: &self.tracks,
|
tracks: &self.tracks,
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::core::*;
|
use crate::core::*;
|
||||||
use crate::model::*;
|
use crate::model::*;
|
||||||
use crate::view::*;
|
use crate::view::*;
|
||||||
pub struct SceneGridViewVertical<'a> {
|
pub struct ArrangerViewVertical<'a> {
|
||||||
pub buf: &'a mut Buffer,
|
pub buf: &'a mut Buffer,
|
||||||
pub area: Rect,
|
pub area: Rect,
|
||||||
pub scenes: &'a[Scene],
|
pub scenes: &'a[Scene],
|
||||||
|
|
@ -10,7 +10,7 @@ pub struct SceneGridViewVertical<'a> {
|
||||||
pub focused: bool,
|
pub focused: bool,
|
||||||
pub entered: bool,
|
pub entered: bool,
|
||||||
}
|
}
|
||||||
impl<'a> SceneGridViewVertical<'a> {
|
impl<'a> ArrangerViewVertical<'a> {
|
||||||
pub fn size (&self) -> (u16, u16) {
|
pub fn size (&self) -> (u16, u16) {
|
||||||
unimplemented!();
|
unimplemented!();
|
||||||
}
|
}
|
||||||
|
|
@ -37,14 +37,12 @@ impl<'a> SceneGridViewVertical<'a> {
|
||||||
} else {
|
} else {
|
||||||
Color::Rgb(20, 45, 5)
|
Color::Rgb(20, 45, 5)
|
||||||
};
|
};
|
||||||
let columns = self.track_names();
|
|
||||||
let mut x2 = x;
|
let mut x2 = x;
|
||||||
for (i, w) in self.track_widths().iter().enumerate() {
|
for (i, w) in self.track_widths().iter().enumerate() {
|
||||||
let focus_column = i == self.cursor.0;
|
let focus_column = i == self.cursor.0;
|
||||||
if x2 >= x + width {
|
if x2 >= x + width {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
//self.separator_v(x2, focus_column);
|
|
||||||
if focus_column {
|
if focus_column {
|
||||||
fill_bg(
|
fill_bg(
|
||||||
&mut self.buf,
|
&mut self.buf,
|
||||||
|
|
@ -53,9 +51,9 @@ impl<'a> SceneGridViewVertical<'a> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
x2 = x2 + w;
|
x2 = x2 + w;
|
||||||
//self.separator_v(x2, focus_column);
|
|
||||||
}
|
}
|
||||||
let (mut x2, y2) = (x, y);
|
let (mut x2, y2) = (x, y);
|
||||||
|
let columns = self.track_names();
|
||||||
for (i, title) in columns.iter().enumerate() {
|
for (i, title) in columns.iter().enumerate() {
|
||||||
let focus_column = i == self.cursor.0;
|
let focus_column = i == self.cursor.0;
|
||||||
if x2 >= x + width {
|
if x2 >= x + width {
|
||||||
|
|
@ -77,7 +75,16 @@ impl<'a> SceneGridViewVertical<'a> {
|
||||||
self.clips(x2+1, y2+2, i - 1);
|
self.clips(x2+1, y2+2, i - 1);
|
||||||
};
|
};
|
||||||
let style = Some(highlight(self.focused, focus_column).bold());
|
let style = Some(highlight(self.focused, focus_column).bold());
|
||||||
title.blit(self.buf, x2+1, y2, style);
|
if i > 0 {
|
||||||
|
"⏺".blit(self.buf, x2, y2, Some(if self.tracks[i-1].recording {
|
||||||
|
Style::default().red()
|
||||||
|
} else if self.tracks[i-1].monitoring {
|
||||||
|
Style::default().green()
|
||||||
|
} else {
|
||||||
|
Style::default().black()
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
title.blit(self.buf, x2+2, y2, style);
|
||||||
x2 = x2 + w + 3;
|
x2 = x2 + w + 3;
|
||||||
}
|
}
|
||||||
fill_bg(
|
fill_bg(
|
||||||
|
|
@ -187,7 +194,7 @@ impl<'a> SceneGridViewVertical<'a> {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct SceneGridViewHorizontal<'a> {
|
pub struct ArrangerViewHorizontal<'a> {
|
||||||
pub buf: &'a mut Buffer,
|
pub buf: &'a mut Buffer,
|
||||||
pub area: Rect,
|
pub area: Rect,
|
||||||
pub scenes: &'a[Scene],
|
pub scenes: &'a[Scene],
|
||||||
|
|
@ -196,7 +203,7 @@ pub struct SceneGridViewHorizontal<'a> {
|
||||||
pub focused: bool,
|
pub focused: bool,
|
||||||
pub entered: bool,
|
pub entered: bool,
|
||||||
}
|
}
|
||||||
impl<'a> SceneGridViewHorizontal<'a> {
|
impl<'a> ArrangerViewHorizontal<'a> {
|
||||||
pub fn size (&self) -> (u16, u16) {
|
pub fn size (&self) -> (u16, u16) {
|
||||||
let w = (4 + longest_track_name(&self.tracks) + self.scenes.len() as u16 * 10) as u16;
|
let w = (4 + longest_track_name(&self.tracks) + self.scenes.len() as u16 * 10) as u16;
|
||||||
let h = (2 + self.tracks.len()) as u16;
|
let h = (2 + self.tracks.len()) as u16;
|
||||||
|
|
@ -1,67 +0,0 @@
|
||||||
use crate::*;
|
|
||||||
|
|
||||||
//trait Focus<T> {
|
|
||||||
//fn focused (&self) -> &T;
|
|
||||||
//fn focused_mut (&mut self) -> &mut T;
|
|
||||||
//fn focus (&mut self, value: T) -> &mut T;
|
|
||||||
//fn focus_next (&mut self) -> &mut T;
|
|
||||||
//fn focus_prev (&mut self) -> &mut T;
|
|
||||||
//fn focus_enter (&mut self) -> &mut T;
|
|
||||||
//fn focus_exit (&mut self) -> &mut T;
|
|
||||||
//}
|
|
||||||
|
|
||||||
//enum AppSection {
|
|
||||||
//Grid,
|
|
||||||
//Sequence,
|
|
||||||
//Chain,
|
|
||||||
//}
|
|
||||||
|
|
||||||
//impl Focus<Self> for (AppSection, bool) {
|
|
||||||
//fn focused (&self) -> &Self {
|
|
||||||
//self
|
|
||||||
//}
|
|
||||||
//fn focused_mut (&mut self) -> &mut Self {
|
|
||||||
//self
|
|
||||||
//}
|
|
||||||
//fn focus (&mut self, value: Self) -> &mut Self {
|
|
||||||
//*self = value;
|
|
||||||
//self
|
|
||||||
//}
|
|
||||||
//fn focus_prev (&mut self) -> &mut Self {
|
|
||||||
//self.focus((match self.0 {
|
|
||||||
//AppSection::Grid => AppSection::Chain,
|
|
||||||
//AppSection::Sequence => AppSection::Grid,
|
|
||||||
//AppSection::Chain => AppSection::Sequence,
|
|
||||||
//}, self.1))
|
|
||||||
//}
|
|
||||||
//fn focus_next (&mut self) -> &mut Self {
|
|
||||||
//self.focus((match self.0 {
|
|
||||||
//AppSection::Grid => AppSection::Sequence,
|
|
||||||
//AppSection::Sequence => AppSection::Chain,
|
|
||||||
//AppSection::Chain => AppSection::Grid,
|
|
||||||
//}, self.1))
|
|
||||||
//}
|
|
||||||
//}
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
App(
|
|
||||||
Column(
|
|
||||||
Transport(
|
|
||||||
Row(PLAY, REC, DUB, MON, BPM, SYNC, QUANT, _, TIME, BBT),
|
|
||||||
RowOrColumn(
|
|
||||||
Grid,
|
|
||||||
|
|
||||||
)
|
|
||||||
|
|
||||||
<App>
|
|
||||||
<Transport />
|
|
||||||
<Grid>
|
|
||||||
<Chains>
|
|
||||||
App
|
|
||||||
\ (Transport)
|
|
||||||
\ Grid
|
|
||||||
\ Chains
|
|
||||||
\ Sequencer + Chain
|
|
||||||
|
|
||||||
*/
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue