mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 11:46:41 +01:00
plugin ins/outs
This commit is contained in:
parent
da1d3220f9
commit
9351887ae6
9 changed files with 187 additions and 64 deletions
|
|
@ -1,6 +1,7 @@
|
||||||
{pkgs?import<nixpkgs>{}}:pkgs.mkShell{
|
{pkgs?import<nixpkgs>{}}:pkgs.mkShell{
|
||||||
nativeBuildInputs = with pkgs; [
|
nativeBuildInputs = with pkgs; [
|
||||||
pkg-config
|
pkg-config
|
||||||
|
freetype
|
||||||
];
|
];
|
||||||
buildInputs = with pkgs; [
|
buildInputs = with pkgs; [
|
||||||
jack2
|
jack2
|
||||||
|
|
@ -10,4 +11,10 @@
|
||||||
];
|
];
|
||||||
VST3_SDK_DIR = "/home/user/Lab/Music/tek/vst3sdk/";
|
VST3_SDK_DIR = "/home/user/Lab/Music/tek/vst3sdk/";
|
||||||
LIBCLANG_PATH = "${pkgs.libclang.lib.outPath}/lib";
|
LIBCLANG_PATH = "${pkgs.libclang.lib.outPath}/lib";
|
||||||
|
LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath (with pkgs; [
|
||||||
|
pipewire.jack
|
||||||
|
# for ChowKick.lv2:
|
||||||
|
freetype
|
||||||
|
libgcc.lib
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
const CONFIG_FILE_NAME: &'static str = "dawdle.toml";
|
const CONFIG_FILE_NAME: &'static str = "tek.toml";
|
||||||
|
const PROJECT_FILE_NAME: &'static str = "project.toml";
|
||||||
|
|
||||||
pub fn create_dirs (xdg: µxdg::XdgApp) -> Result<(), Box<dyn Error>> {
|
pub fn create_dirs (xdg: µxdg::XdgApp) -> Result<(), Box<dyn Error>> {
|
||||||
use std::{path::Path,fs::{File,create_dir_all}};
|
use std::{path::Path,fs::{File,create_dir_all}};
|
||||||
|
|
@ -19,5 +20,10 @@ pub fn create_dirs (xdg: µxdg::XdgApp) -> Result<(), Box<dyn Error>> {
|
||||||
println!("Creating {data_dir:?}");
|
println!("Creating {data_dir:?}");
|
||||||
create_dir_all(&data_dir)?;
|
create_dir_all(&data_dir)?;
|
||||||
}
|
}
|
||||||
|
let project_path = data_dir.join(PROJECT_FILE_NAME);
|
||||||
|
if !Path::new(&project_path).exists() {
|
||||||
|
println!("Creating {project_path:?}");
|
||||||
|
File::create_new(&project_path)?;
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,11 @@ pub use self::launcher::Launcher;
|
||||||
use crossterm::event;
|
use crossterm::event;
|
||||||
use ::jack::{AudioIn, AudioOut, MidiIn, MidiOut, Port, PortSpec, Client};
|
use ::jack::{AudioIn, AudioOut, MidiIn, MidiOut, Port, PortSpec, Client};
|
||||||
|
|
||||||
pub trait Device: Render + Handle + PortList + Send + Sync {}
|
pub trait Device: Render + Handle + PortList + Send + Sync {
|
||||||
|
fn boxed (self) -> Box<dyn Device> where Self: Sized + 'static {
|
||||||
|
Box::new(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn run (device: impl Device + Send + Sync + 'static) -> Result<(), Box<dyn Error>> {
|
pub fn run (device: impl Device + Send + Sync + 'static) -> Result<(), Box<dyn Error>> {
|
||||||
let device = Arc::new(Mutex::new(device));
|
let device = Arc::new(Mutex::new(device));
|
||||||
|
|
@ -138,7 +142,7 @@ pub trait PortList {
|
||||||
fn midi_outs (&self) -> Usually<Vec<String>> {
|
fn midi_outs (&self) -> Usually<Vec<String>> {
|
||||||
Ok(vec![])
|
Ok(vec![])
|
||||||
}
|
}
|
||||||
fn connect (&mut self, connect: bool, source: &str, target: &str)
|
fn connect (&mut self, _connect: bool, _source: &str, _target: &str)
|
||||||
-> Usually<()>
|
-> Usually<()>
|
||||||
{
|
{
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
||||||
|
|
@ -121,16 +121,35 @@ impl Launcher {
|
||||||
],
|
],
|
||||||
chains: vec![
|
chains: vec![
|
||||||
Chain::new("Chain#0000", vec![
|
Chain::new("Chain#0000", vec![
|
||||||
Box::new(Plugin::new("Plugin#000")?),
|
Plugin::lv2(
|
||||||
|
"Plugin#000",
|
||||||
|
"file:///home/user/.lv2/ChowKick.lv2",
|
||||||
|
&[1, 1, 0, 2]
|
||||||
|
)?.boxed(),
|
||||||
])?,
|
])?,
|
||||||
|
|
||||||
Chain::new("Chain#0000", vec![
|
Chain::new("Chain#0000", vec![
|
||||||
Box::new(Plugin::new("Plugin#001")?),
|
Plugin::lv2(
|
||||||
|
"Plugin#001",
|
||||||
|
"file:///home/user/.lv2/Helm.lv2",
|
||||||
|
&[1, 0, 0, 2]
|
||||||
|
)?.boxed(),
|
||||||
])?,
|
])?,
|
||||||
|
|
||||||
Chain::new("Chain#0000", vec![
|
Chain::new("Chain#0000", vec![
|
||||||
Box::new(Plugin::new("Plugin#002")?),
|
Plugin::lv2(
|
||||||
|
"Plugin#002",
|
||||||
|
"file:///home/user/.lv2/Helm.lv2",
|
||||||
|
&[1, 0, 0, 2]
|
||||||
|
)?.boxed(),
|
||||||
])?,
|
])?,
|
||||||
|
|
||||||
Chain::new("Chain#0000", vec![
|
Chain::new("Chain#0000", vec![
|
||||||
Box::new(Plugin::new("Plugin#003")?),
|
Plugin::lv2(
|
||||||
|
"Plugin#003",
|
||||||
|
"file:///home/user/.lv2/Odin2.lv2",
|
||||||
|
&[1, 0, 0, 2]
|
||||||
|
)?.boxed(),
|
||||||
])?,
|
])?,
|
||||||
],
|
],
|
||||||
timebase,
|
timebase,
|
||||||
|
|
@ -506,18 +525,27 @@ fn play_toggle (s: &mut Launcher) -> Usually<bool> {
|
||||||
};
|
};
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
fn play_start (s: &mut Launcher) -> Usually<bool> {
|
fn play_start (_: &mut Launcher) -> Usually<bool> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
fn record_toggle (s: &mut Launcher) -> Usually<bool> {
|
fn record_toggle (s: &mut Launcher) -> Usually<bool> {
|
||||||
s.recording = !s.recording;
|
s.recording = !s.recording;
|
||||||
|
for sequencer in s.tracks.iter() {
|
||||||
|
sequencer.state().recording = s.recording;
|
||||||
|
}
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
fn overdub_toggle (s: &mut Launcher) -> Usually<bool> {
|
fn overdub_toggle (s: &mut Launcher) -> Usually<bool> {
|
||||||
s.overdub = !s.overdub;
|
s.overdub = !s.overdub;
|
||||||
|
for sequencer in s.tracks.iter() {
|
||||||
|
sequencer.state().overdub = s.overdub;
|
||||||
|
}
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
fn monitor_toggle (s: &mut Launcher) -> Usually<bool> {
|
fn monitor_toggle (s: &mut Launcher) -> Usually<bool> {
|
||||||
s.monitoring = !s.monitoring;
|
s.monitoring = !s.monitoring;
|
||||||
|
for sequencer in s.tracks.iter() {
|
||||||
|
sequencer.state().monitoring = s.monitoring;
|
||||||
|
}
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,14 +5,16 @@ mod vst2;
|
||||||
mod vst3;
|
mod vst3;
|
||||||
|
|
||||||
pub struct Plugin {
|
pub struct Plugin {
|
||||||
name: String,
|
name: String,
|
||||||
path: String,
|
path: Option<String>,
|
||||||
plugin: Option<PluginKind>,
|
plugin: Option<PluginKind>,
|
||||||
offset: usize,
|
offset: usize,
|
||||||
selected: usize,
|
selected: usize,
|
||||||
mapping: bool,
|
mapping: bool,
|
||||||
midi_in: ::jack::Port<::jack::MidiIn>,
|
midi_ins: Vec<Port<MidiIn>>,
|
||||||
audio_out: [::jack::Port<::jack::AudioOut>;2],
|
midi_outs: Vec<Port<MidiOut>>,
|
||||||
|
audio_ins: Vec<Port<AudioIn>>,
|
||||||
|
audio_outs: Vec<Port<AudioOut>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
enum PluginKind {
|
enum PluginKind {
|
||||||
|
|
@ -31,44 +33,100 @@ enum PluginKind {
|
||||||
const HELM: &'static str = "file:///nix/store/ij3sz7nqg5l7v2dygdvzy3w6cj62bd6r-helm-0.9.0/lib/lv2/helm.lv2";
|
const HELM: &'static str = "file:///nix/store/ij3sz7nqg5l7v2dygdvzy3w6cj62bd6r-helm-0.9.0/lib/lv2/helm.lv2";
|
||||||
|
|
||||||
impl Plugin {
|
impl Plugin {
|
||||||
pub fn new (name: &str) -> Result<DynamicDevice<Self>, Box<dyn Error>> {
|
/// Load a LV2 plugin.
|
||||||
|
pub fn lv2 (name: &str, path: &str, ports: &[usize;4]) -> Usually<DynamicDevice<Self>> {
|
||||||
|
let plugin = Self::new(name, ports)?;
|
||||||
|
let mut state = plugin.state();
|
||||||
|
state.plugin = Some(self::lv2::plug(path)?);
|
||||||
|
state.path = Some(String::from(path));
|
||||||
|
std::mem::drop(state);
|
||||||
|
Ok(plugin)
|
||||||
|
}
|
||||||
|
pub fn new (name: &str, ports: &[usize;4]) -> Usually<DynamicDevice<Self>> {
|
||||||
let (client, _status) = Client::new(name, ClientOptions::NO_START_SERVER)?;
|
let (client, _status) = Client::new(name, ClientOptions::NO_START_SERVER)?;
|
||||||
|
let [midi_ins, midi_outs, audio_ins, audio_outs] = ports;
|
||||||
DynamicDevice::new(render, handle, Self::process, Self {
|
DynamicDevice::new(render, handle, Self::process, Self {
|
||||||
name: name.into(),
|
name: name.into(),
|
||||||
path: HELM.into(),
|
path: None,
|
||||||
plugin: Some(self::lv2::plug(HELM)?),
|
plugin: None,
|
||||||
offset: 0,
|
offset: 0,
|
||||||
selected: 0,
|
selected: 0,
|
||||||
mapping: false,
|
mapping: false,
|
||||||
midi_in: client.register_port("in", MidiIn::default())?,
|
midi_ins: {
|
||||||
audio_out: [
|
let mut ports = vec![];
|
||||||
client.register_port("outL", AudioOut::default())?,
|
for i in 0..*midi_ins {
|
||||||
client.register_port("outR", AudioOut::default())?,
|
ports.push(client.register_port(&format!("midi-in-{i}"), MidiIn::default())?)
|
||||||
],
|
}
|
||||||
|
ports
|
||||||
|
},
|
||||||
|
midi_outs: {
|
||||||
|
let mut ports = vec![];
|
||||||
|
for i in 0..*midi_outs {
|
||||||
|
ports.push(client.register_port(&format!("midi-out-{i}"), MidiOut::default())?)
|
||||||
|
}
|
||||||
|
ports
|
||||||
|
},
|
||||||
|
audio_ins: {
|
||||||
|
let mut ports = vec![];
|
||||||
|
for i in 0..*audio_ins {
|
||||||
|
ports.push(client.register_port(&format!("audio-in-{i}"), AudioIn::default())?)
|
||||||
|
}
|
||||||
|
ports
|
||||||
|
},
|
||||||
|
audio_outs: {
|
||||||
|
let mut ports = vec![];
|
||||||
|
for i in 0..*audio_outs {
|
||||||
|
ports.push(client.register_port(&format!("audio-out-{i}"), AudioOut::default())?)
|
||||||
|
}
|
||||||
|
ports
|
||||||
|
},
|
||||||
}).activate(client)
|
}).activate(client)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn process (&mut self, _: &Client, scope: &ProcessScope) -> Control {
|
pub fn process (&mut self, _: &Client, scope: &ProcessScope) -> Control {
|
||||||
match self.plugin.as_mut() {
|
match self.plugin.as_mut() {
|
||||||
Some(PluginKind::LV2 { features, ref mut instance, .. }) => {
|
Some(PluginKind::LV2 { features, ref mut instance, .. }) => {
|
||||||
let mut input = ::livi::event::LV2AtomSequence::new(
|
|
||||||
&features, scope.n_frames() as usize
|
|
||||||
);
|
|
||||||
let urid = features.midi_urid();
|
let urid = features.midi_urid();
|
||||||
for event in self.midi_in.iter(scope) {
|
let mut inputs = vec![];
|
||||||
match event.bytes.len() {
|
for port in self.midi_ins.iter() {
|
||||||
3 => input.push_midi_event::<3>(
|
let mut atom = ::livi::event::LV2AtomSequence::new(
|
||||||
event.time as i64,
|
&features,
|
||||||
urid,
|
scope.n_frames() as usize
|
||||||
&event.bytes[0..3]
|
);
|
||||||
).unwrap(),
|
for event in port.iter(scope) {
|
||||||
_ => {}
|
match event.bytes.len() {
|
||||||
|
3 => atom.push_midi_event::<3>(
|
||||||
|
event.time as i64,
|
||||||
|
urid,
|
||||||
|
&event.bytes[0..3]
|
||||||
|
).unwrap(),
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
inputs.push(atom);
|
||||||
|
}
|
||||||
|
let mut outputs = vec![];
|
||||||
|
for port in self.midi_outs.iter() {
|
||||||
|
outputs.push(::livi::event::LV2AtomSequence::new(
|
||||||
|
&features,
|
||||||
|
scope.n_frames() as usize
|
||||||
|
));
|
||||||
}
|
}
|
||||||
let ports = ::livi::EmptyPortConnections::new()
|
let ports = ::livi::EmptyPortConnections::new()
|
||||||
.with_atom_sequence_inputs(std::iter::once(&input))
|
.with_atom_sequence_inputs(
|
||||||
.with_audio_outputs(self.audio_out.iter_mut().map(|o|o.as_mut_slice(scope)));
|
inputs.iter()
|
||||||
unsafe { instance.run(scope.n_frames() as usize, ports).unwrap() };
|
)
|
||||||
|
.with_atom_sequence_outputs(
|
||||||
|
outputs.iter_mut()
|
||||||
|
)
|
||||||
|
.with_audio_inputs(
|
||||||
|
self.audio_ins.iter().map(|o|o.as_slice(scope))
|
||||||
|
)
|
||||||
|
.with_audio_outputs(
|
||||||
|
self.audio_outs.iter_mut().map(|o|o.as_mut_slice(scope))
|
||||||
|
);
|
||||||
|
unsafe {
|
||||||
|
instance.run(scope.n_frames() as usize, ports).unwrap()
|
||||||
|
};
|
||||||
},
|
},
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
@ -77,16 +135,33 @@ impl Plugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PortList for Plugin {
|
impl PortList for Plugin {
|
||||||
fn midi_ins (&self) -> Usually<Vec<String>> {
|
fn audio_ins (&self) -> Usually<Vec<String>> {
|
||||||
Ok(vec![
|
let mut ports = vec![];
|
||||||
self.midi_in.name()?
|
for port in self.audio_ins.iter() {
|
||||||
])
|
ports.push(port.name()?);
|
||||||
|
}
|
||||||
|
Ok(ports)
|
||||||
}
|
}
|
||||||
fn audio_outs (&self) -> Usually<Vec<String>> {
|
fn audio_outs (&self) -> Usually<Vec<String>> {
|
||||||
Ok(vec![
|
let mut ports = vec![];
|
||||||
self.audio_out[0].name()?,
|
for port in self.audio_outs.iter() {
|
||||||
self.audio_out[1].name()?
|
ports.push(port.name()?);
|
||||||
])
|
}
|
||||||
|
Ok(ports)
|
||||||
|
}
|
||||||
|
fn midi_ins (&self) -> Usually<Vec<String>> {
|
||||||
|
let mut ports = vec![];
|
||||||
|
for port in self.midi_ins.iter() {
|
||||||
|
ports.push(port.name()?);
|
||||||
|
}
|
||||||
|
Ok(ports)
|
||||||
|
}
|
||||||
|
fn midi_outs (&self) -> Usually<Vec<String>> {
|
||||||
|
let mut ports = vec![];
|
||||||
|
for port in self.midi_outs.iter() {
|
||||||
|
ports.push(port.name()?);
|
||||||
|
}
|
||||||
|
Ok(ports)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -100,10 +175,13 @@ pub fn render (state: &Plugin, buf: &mut Buffer, area: Rect)
|
||||||
match &state.plugin {
|
match &state.plugin {
|
||||||
Some(PluginKind::LV2 { portList, instance, .. }) => {
|
Some(PluginKind::LV2 { portList, instance, .. }) => {
|
||||||
for i in 0..height - 4 {
|
for i in 0..height - 4 {
|
||||||
let port = &portList[i as usize];
|
if let Some(port) = portList.get(i as usize) {
|
||||||
let label = &format!("C·· M·· {:25} = {:03}", port.name, port.default_value);
|
let label = &format!("C·· M·· {:25} = {:03}", port.name, port.default_value);
|
||||||
width = width.max(label.len() as u16);
|
width = width.max(label.len() as u16);
|
||||||
label.blit(buf, x + 2, y + 3 + i as u16, None);
|
label.blit(buf, x + 2, y + 3 + i as u16, None);
|
||||||
|
} else {
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
draw_box(buf, Rect { x, y, width, height });
|
draw_box(buf, Rect { x, y, width, height });
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -44,13 +44,13 @@ pub struct Sequencer {
|
||||||
notes_on: Vec<bool>,
|
notes_on: Vec<bool>,
|
||||||
|
|
||||||
/// Play sequence to output.
|
/// Play sequence to output.
|
||||||
playing: TransportState,
|
pub playing: TransportState,
|
||||||
/// Play input through output.
|
/// Play input through output.
|
||||||
monitoring: bool,
|
pub monitoring: bool,
|
||||||
/// Write input to sequence.
|
/// Write input to sequence.
|
||||||
recording: bool,
|
pub recording: bool,
|
||||||
/// Don't delete when recording.
|
/// Don't delete when recording.
|
||||||
overdub: bool,
|
pub overdub: bool,
|
||||||
|
|
||||||
/// Display mode
|
/// Display mode
|
||||||
mode: SequencerView,
|
mode: SequencerView,
|
||||||
|
|
@ -171,7 +171,7 @@ impl Sequencer {
|
||||||
frame.push(event.bytes.into())
|
frame.push(event.bytes.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if self.recording {
|
if self.recording && self.playing == TransportState::Rolling {
|
||||||
let contains = sequence.contains_key(&tick);
|
let contains = sequence.contains_key(&tick);
|
||||||
if contains {
|
if contains {
|
||||||
sequence.get_mut(&tick).unwrap().push(message.clone());
|
sequence.get_mut(&tick).unwrap().push(message.clone());
|
||||||
|
|
@ -191,7 +191,7 @@ impl Sequencer {
|
||||||
frame.push(event.bytes.into())
|
frame.push(event.bytes.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if self.recording {
|
if self.recording && self.playing == TransportState::Rolling {
|
||||||
let contains = sequence.contains_key(&tick);
|
let contains = sequence.contains_key(&tick);
|
||||||
if contains {
|
if contains {
|
||||||
sequence.get_mut(&tick).unwrap().push(message.clone());
|
sequence.get_mut(&tick).unwrap().push(message.clone());
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ impl Column {
|
||||||
let mut w = 0u16;
|
let mut w = 0u16;
|
||||||
let mut h = 0u16;
|
let mut h = 0u16;
|
||||||
let mut rects = vec![];
|
let mut rects = vec![];
|
||||||
for (i, device) in items.iter().enumerate() {
|
for (_i, device) in items.iter().enumerate() {
|
||||||
let y = area.y + h;
|
let y = area.y + h;
|
||||||
let rect = Rect { x: area.x, y, width: area.width, height: area.height - h };
|
let rect = Rect { x: area.x, y, width: area.width, height: area.height - h };
|
||||||
let result = device.render(buf, rect)?;
|
let result = device.render(buf, rect)?;
|
||||||
|
|
@ -43,7 +43,7 @@ impl Row {
|
||||||
let mut w = 0u16;
|
let mut w = 0u16;
|
||||||
let mut h = 0u16;
|
let mut h = 0u16;
|
||||||
let mut rects = vec![];
|
let mut rects = vec![];
|
||||||
for (i, device) in items.iter().enumerate() {
|
for (_i, device) in items.iter().enumerate() {
|
||||||
let x = area.x + w;
|
let x = area.x + w;
|
||||||
let rect = Rect { x, y: area.y, width: area.width - w, height: area.height };
|
let rect = Rect { x, y: area.y, width: area.width - w, height: area.height };
|
||||||
let result = device.render(buf, rect)?;
|
let result = device.render(buf, rect)?;
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ impl Handle for FocusColumn {
|
||||||
|
|
||||||
impl Render for FocusColumn {
|
impl Render for FocusColumn {
|
||||||
fn render (&self, buf: &mut Buffer, area: Rect) -> Usually<Rect> {
|
fn render (&self, buf: &mut Buffer, area: Rect) -> Usually<Rect> {
|
||||||
let (rect, rects) = Column::draw(buf, area, self.1.0.as_ref(), 0)?;
|
let (rect, _rects) = Column::draw(buf, area, self.1.0.as_ref(), 0)?;
|
||||||
//if i == self.focus {
|
//if i == self.focus {
|
||||||
//if self.focused {
|
//if self.focused {
|
||||||
//draw_box_styled(buf, result, Some(Style::default().white().not_dim()))
|
//draw_box_styled(buf, result, Some(Style::default().white().not_dim()))
|
||||||
|
|
@ -99,7 +99,7 @@ impl Focus for FocusColumn {
|
||||||
_ => false
|
_ => false
|
||||||
},
|
},
|
||||||
FocusEvent::Outward => match self.0 {
|
FocusEvent::Outward => match self.0 {
|
||||||
Some(i) => {
|
Some(_i) => {
|
||||||
self.0 = None;
|
self.0 = None;
|
||||||
true
|
true
|
||||||
},
|
},
|
||||||
|
|
@ -119,7 +119,7 @@ impl Handle for FocusRow {
|
||||||
|
|
||||||
impl Render for FocusRow {
|
impl Render for FocusRow {
|
||||||
fn render (&self, buf: &mut Buffer, area: Rect) -> Usually<Rect> {
|
fn render (&self, buf: &mut Buffer, area: Rect) -> Usually<Rect> {
|
||||||
let (rect, rects) = Row::draw(buf, area, &self.1.0, 0)?;
|
let (rect, _rects) = Row::draw(buf, area, &self.1.0, 0)?;
|
||||||
Ok(rect)
|
Ok(rect)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -177,7 +177,7 @@ impl Focus for FocusRow {
|
||||||
_ => false
|
_ => false
|
||||||
},
|
},
|
||||||
FocusEvent::Outward => match self.0 {
|
FocusEvent::Outward => match self.0 {
|
||||||
Some(i) => {
|
Some(_i) => {
|
||||||
self.0 = None;
|
self.0 = None;
|
||||||
true
|
true
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ use crate::prelude::*;
|
||||||
|
|
||||||
fn main () -> Result<(), Box<dyn Error>> {
|
fn main () -> Result<(), Box<dyn Error>> {
|
||||||
let _cli = cli::Cli::parse();
|
let _cli = cli::Cli::parse();
|
||||||
let xdg = microxdg::XdgApp::new("dawdle")?;
|
let xdg = microxdg::XdgApp::new("tek")?;
|
||||||
crate::config::create_dirs(&xdg)?;
|
crate::config::create_dirs(&xdg)?;
|
||||||
run(Launcher::new_with_controller(
|
run(Launcher::new_with_controller(
|
||||||
"Launcher#0",
|
"Launcher#0",
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue