mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 19:56:42 +01:00
border style macro
This commit is contained in:
parent
afa2a2fd2b
commit
117f4d5363
4 changed files with 123 additions and 139 deletions
26
src/main.rs
26
src/main.rs
|
|
@ -9,21 +9,21 @@ extern crate clap;
|
|||
extern crate jack as _jack;
|
||||
extern crate crossterm;
|
||||
|
||||
pub mod cli;
|
||||
pub mod config;
|
||||
pub mod control;
|
||||
pub mod core;
|
||||
pub mod model;
|
||||
pub mod view;
|
||||
pub mod jack;
|
||||
pub mod edn;
|
||||
mod cli;
|
||||
mod config;
|
||||
mod control;
|
||||
mod core;
|
||||
mod model;
|
||||
mod view;
|
||||
mod jack;
|
||||
mod edn;
|
||||
|
||||
use crate::{core::*, model::*};
|
||||
|
||||
/// Application entrypoint.
|
||||
pub fn main () -> Usually<()> {
|
||||
let midi_from = ["nanoKEY Studio.*capture.*"];
|
||||
let audio_into = ["Komplete.+:playback_FL", "Komplete.+:playback_FR"];
|
||||
fn main () -> Usually<()> {
|
||||
let controller = ["nanoKEY Studio.*capture.*"];
|
||||
let soundsystem = ["Komplete.+:playback_FL", "Komplete.+:playback_FR"];
|
||||
// Start main loop
|
||||
App::new()?.run(Some(|app: Arc<RwLock<App>>|{
|
||||
let mut state = app.write().unwrap();
|
||||
|
|
@ -32,7 +32,7 @@ pub fn main () -> Usually<()> {
|
|||
let client = jack.as_client();
|
||||
state.transport = Some(client.transport());
|
||||
state.midi_in = Some(client.register_port("midi-in", MidiIn)?);
|
||||
let _ = midi_from
|
||||
controller
|
||||
.iter()
|
||||
.map(|name|client
|
||||
.ports(Some(name), None, PortFlags::empty())
|
||||
|
|
@ -45,7 +45,7 @@ pub fn main () -> Usually<()> {
|
|||
})
|
||||
.collect::<Usually<()>>())
|
||||
.collect::<Usually<()>>()?;
|
||||
state.audio_outs = audio_into
|
||||
state.audio_outs = soundsystem
|
||||
.iter()
|
||||
.map(|name|client
|
||||
.ports(Some(name), None, PortFlags::empty())
|
||||
|
|
|
|||
|
|
@ -17,12 +17,11 @@ pub use self::sequencer::SequencerView;
|
|||
use crate::{render, App, core::*};
|
||||
|
||||
render!(App |self, buf, area| {
|
||||
let track = self.track_cursor;
|
||||
Split::down([
|
||||
&TransportView::new(self),
|
||||
&Split::down([
|
||||
&ArrangerView::new(&self, !self.arranger_mode),
|
||||
&If(track > 0, &Split::right([
|
||||
&If(self.track_cursor > 0, &Split::right([
|
||||
&ChainView::vertical(&self),
|
||||
&SequencerView::new(&self),
|
||||
]))
|
||||
|
|
|
|||
|
|
@ -10,154 +10,139 @@ pub trait BorderStyle {
|
|||
const SW: &'static str = "";
|
||||
const W: &'static str = "";
|
||||
|
||||
#[inline]
|
||||
fn draw (&self, buf: &mut Buffer, area: Rect) {
|
||||
self.draw_horizontal(buf, area);
|
||||
self.draw_vertical(buf, area);
|
||||
self.draw_corners(buf, area);
|
||||
self.draw_horizontal(buf, area, None);
|
||||
self.draw_vertical(buf, area, None);
|
||||
self.draw_corners(buf, area, None);
|
||||
}
|
||||
|
||||
fn draw_horizontal (&self, buf: &mut Buffer, area: Rect) {
|
||||
let style = self.style();
|
||||
#[inline]
|
||||
fn draw_horizontal (&self, buf: &mut Buffer, area: Rect, style: Option<Style>) {
|
||||
let style = style.or_else(||self.style_horizontal());
|
||||
for x in area.x..(area.x+area.width).saturating_sub(1) {
|
||||
Self::N.blit(buf, x, area.y, style);
|
||||
Self::S.blit(buf, x, area.y + area.height - 1, style);
|
||||
self.draw_north(buf, x, area.y, style);
|
||||
self.draw_south(buf, x, (area.y + area.height).saturating_sub(1), style);
|
||||
}
|
||||
}
|
||||
#[inline]
|
||||
fn draw_north (&self, buf: &mut Buffer, x: u16, y: u16, style: Option<Style>) {
|
||||
Self::N.blit(buf, x, y, style);
|
||||
}
|
||||
#[inline]
|
||||
fn draw_south (&self, buf: &mut Buffer, x: u16, y: u16, style: Option<Style>) {
|
||||
Self::S.blit(buf, x, y, style);
|
||||
}
|
||||
|
||||
fn draw_vertical (&self, buf: &mut Buffer, area: Rect) {
|
||||
let style = self.style();
|
||||
#[inline]
|
||||
fn draw_vertical (&self, buf: &mut Buffer, area: Rect, style: Option<Style>) {
|
||||
let style = style.or_else(||self.style_vertical());
|
||||
for y in area.y..(area.y+area.height).saturating_sub(1) {
|
||||
Self::W.blit(buf, area.x, y, style);
|
||||
Self::E.blit(buf, area.x + area.width - 1, y, style);
|
||||
}
|
||||
}
|
||||
|
||||
fn draw_corners (&self, buf: &mut Buffer, area: Rect) {
|
||||
let style = self.style();
|
||||
#[inline]
|
||||
fn draw_corners (&self, buf: &mut Buffer, area: Rect, style: Option<Style>) {
|
||||
let style = style.or_else(||self.style_corners());
|
||||
Self::NW.blit(buf, area.x, area.y, style);
|
||||
Self::NE.blit(buf, area.x + area.width - 1, area.y, style);
|
||||
Self::SW.blit(buf, area.x, area.y + area.height - 1, style);
|
||||
Self::SE.blit(buf, area.x + area.width - 1, area.y + area.height - 1, style);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn style (&self) -> Option<Style> {
|
||||
None
|
||||
}
|
||||
#[inline]
|
||||
fn style_horizontal (&self) -> Option<Style> {
|
||||
self.style()
|
||||
}
|
||||
#[inline]
|
||||
fn style_vertical (&self) -> Option<Style> {
|
||||
self.style()
|
||||
}
|
||||
#[inline]
|
||||
fn style_corners (&self) -> Option<Style> {
|
||||
self.style()
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! border {
|
||||
($($T:ty {
|
||||
$nw:literal $n:literal $ne:literal $w:literal $e:literal $sw:literal $s:literal $se:literal
|
||||
$($x:tt)*
|
||||
}),+) => {
|
||||
$(impl BorderStyle for $T {
|
||||
const NW: &'static str = $nw;
|
||||
const N: &'static str = $n;
|
||||
const NE: &'static str = $ne;
|
||||
const W: &'static str = $w;
|
||||
const E: &'static str = $e;
|
||||
const SW: &'static str = $sw;
|
||||
const S: &'static str = $s;
|
||||
const SE: &'static str = $se;
|
||||
$($x)*
|
||||
})+
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Lozenge(pub Style);
|
||||
|
||||
impl BorderStyle for Lozenge {
|
||||
const N: &'static str = "─";
|
||||
const S: &'static str = "─";
|
||||
const NW: &'static str = "╭";
|
||||
const W: &'static str = "│";
|
||||
const SW: &'static str = "╰";
|
||||
const NE: &'static str = "╮";
|
||||
const E: &'static str = "│";
|
||||
const SE: &'static str = "╯";
|
||||
|
||||
fn style (&self) -> Option<Style> {
|
||||
Some(self.0)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct LozengeV(pub Style);
|
||||
pub struct LozengeDotted(pub Style);
|
||||
pub struct Quarter(pub Style);
|
||||
|
||||
impl BorderStyle for Quarter {
|
||||
const N: &'static str = "▔";
|
||||
const S: &'static str = "▁";
|
||||
const NW: &'static str = "▎";
|
||||
const W: &'static str = "▎";
|
||||
const SW: &'static str = "▎";
|
||||
const NE: &'static str = "🮇";
|
||||
const E: &'static str = "🮇";
|
||||
const SE: &'static str = "🮇";
|
||||
|
||||
fn style (&self) -> Option<Style> {
|
||||
Some(self.0)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct QuarterV(pub Style);
|
||||
pub struct Chamfer(pub Style);
|
||||
|
||||
impl BorderStyle for QuarterV {
|
||||
const NW: &'static str = "▎";
|
||||
const W: &'static str = "▎";
|
||||
const SW: &'static str = "▎";
|
||||
const NE: &'static str = "🮇";
|
||||
const E: &'static str = "🮇";
|
||||
const SE: &'static str = "🮇";
|
||||
|
||||
fn style (&self) -> Option<Style> {
|
||||
Some(self.0)
|
||||
border! {
|
||||
Lozenge {
|
||||
"╭" "─" "╮"
|
||||
"│" "│"
|
||||
"╰" "─" "╯"
|
||||
fn style (&self) -> Option<Style> {
|
||||
Some(self.0)
|
||||
}
|
||||
},
|
||||
LozengeV {
|
||||
"╭" "" "╮"
|
||||
"│" "│"
|
||||
"╰" "" "╯"
|
||||
fn style (&self) -> Option<Style> {
|
||||
Some(self.0)
|
||||
}
|
||||
},
|
||||
LozengeDotted {
|
||||
"╭" "┅" "╮"
|
||||
"┇" "┇"
|
||||
"╰" "┅" "╯"
|
||||
fn style (&self) -> Option<Style> {
|
||||
Some(self.0)
|
||||
}
|
||||
},
|
||||
Quarter {
|
||||
"▎" "▔" "🮇"
|
||||
"▎" "🮇"
|
||||
"▎" "▁" "🮇"
|
||||
fn style (&self) -> Option<Style> {
|
||||
Some(self.0)
|
||||
}
|
||||
},
|
||||
QuarterV {
|
||||
"▎" "" "🮇"
|
||||
"▎" "🮇"
|
||||
"▎" "" "🮇"
|
||||
fn style (&self) -> Option<Style> {
|
||||
Some(self.0)
|
||||
}
|
||||
},
|
||||
Chamfer {
|
||||
"🭂" "▔" "🭍"
|
||||
"▎" "🮇"
|
||||
"🭓" "▁" "🭞"
|
||||
fn style (&self) -> Option<Style> {
|
||||
Some(self.0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const LOZENGE: [[&'static str;3];3] = [
|
||||
["╭", "─", "╮"],
|
||||
["│", " ", "│"],
|
||||
["╰", "─", "╯"],
|
||||
];
|
||||
|
||||
pub fn lozenge_left (buf: &mut Buffer, x: u16, y1: u16, h: u16, style: Option<Style>) {
|
||||
let y2 = y1 + h;
|
||||
let y3 = y2.saturating_sub(1);
|
||||
for y in y1..y2 {
|
||||
if y == y1 {
|
||||
LOZENGE[0][0]
|
||||
} else if y == y3 {
|
||||
LOZENGE[2][0]
|
||||
} else {
|
||||
LOZENGE[1][0]
|
||||
}.blit(buf, x, y, style)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn lozenge_right (buf: &mut Buffer, x: u16, y1: u16, h: u16, style: Option<Style>) {
|
||||
let y2 = y1 + h;
|
||||
let y3 = y2.saturating_sub(1);
|
||||
for y in y1..y2 {
|
||||
if y == y1 {
|
||||
LOZENGE[0][2]
|
||||
} else if y == y3 {
|
||||
LOZENGE[2][2]
|
||||
} else {
|
||||
LOZENGE[1][2]
|
||||
}.blit(buf, x, y, style)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn draw_box (buffer: &mut Buffer, area: Rect) -> Rect {
|
||||
draw_box_styled(buffer, area, Some(Style::default().gray().dim()))
|
||||
}
|
||||
|
||||
pub fn draw_box_styled (buffer: &mut Buffer, area: Rect, style: Option<Style>) -> Rect {
|
||||
if area.width < 1 || area.height < 1 {
|
||||
return area
|
||||
}
|
||||
format!("╭{}╮", "─".repeat((area.width - 2).into()))
|
||||
.blit(buffer, area.x, area.y, style);
|
||||
for y in (area.y + 1)..(area.y + area.height - 1) {
|
||||
"│".blit(buffer, area.x, y, style);
|
||||
"│".blit(buffer, area.x + area.width - 1, y, style);
|
||||
}
|
||||
format!("╰{}╯", "─".repeat((area.width - 2).into()))
|
||||
.blit(buffer, area.x, area.y + area.height - 1, style);
|
||||
area
|
||||
}
|
||||
|
||||
pub fn draw_box_styled_dotted (buffer: &mut Buffer, area: Rect, style: Option<Style>) -> Rect {
|
||||
if area.width < 1 || area.height < 1 {
|
||||
return area
|
||||
}
|
||||
format!("╭{}╮", "┅".repeat((area.width - 2).into()))
|
||||
.blit(buffer, area.x, area.y, style);
|
||||
for y in (area.y + 1)..(area.y + area.height - 1) {
|
||||
"┇".blit(buffer, area.x, y, style);
|
||||
"┇".blit(buffer, area.x + area.width - 1, y, style);
|
||||
}
|
||||
format!("╰{}╯", "┅".repeat((area.width - 2).into()))
|
||||
.blit(buffer, area.x, area.y + area.height - 1, style);
|
||||
area
|
||||
}
|
||||
|
|
|
|||
|
|
@ -97,8 +97,7 @@ impl<'a> ChainView<'a> {
|
|||
} else {
|
||||
style
|
||||
};
|
||||
lozenge_left(buf, x + x2, y, frame.height, style);
|
||||
lozenge_right(buf, x + x2 + frame.width - 1, y, frame.height, style);
|
||||
LozengeV(style.unwrap_or(Style::default())).draw(buf, frame);
|
||||
//let mut y2 = 1u16;
|
||||
//for port in device.midi_outs()?.iter() {
|
||||
//port.blit(buf, x + x2 + frame.width, y + y2, Some(Style::default()));
|
||||
|
|
@ -165,7 +164,8 @@ impl<'a> ChainView<'a> {
|
|||
//}
|
||||
}
|
||||
if frames.len() > 0 {
|
||||
draw_box_styled(buf, frames[track.device], selected);
|
||||
Lozenge(selected.unwrap_or(Style::default()))
|
||||
.draw(buf, frames[track.device]);
|
||||
}
|
||||
Ok((Rect { x, y: area.y, width: w, height: y - area.y }, frames))
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue