//handle!(TuiIn: |self: Sampler, input|SamplerCommand::execute_with_state(self, input.event())); //input_to_command!(SamplerCommand: |state: Sampler, input: Event|match state.mode{ //Some(SamplerMode::Import(..)) => Self::Import( //FileBrowserCommand::input_to_command(state, input)? //), //_ => match input { //// load sample //kpat!(Shift-Char('L')) => Self::Import(FileBrowserCommand::Begin), //kpat!(KeyCode::Up) => Self::Select(state.note_pos().overflowing_add(1).0.min(127)), //kpat!(KeyCode::Down) => Self::Select(state.note_pos().overflowing_sub(1).0.min(127)), //_ => return None //} //}); //impl Handle for AddSampleModal { //fn handle (&mut self, from: &TuiIn) -> Perhaps { //if from.handle_keymap(self, KEYMAP_ADD_SAMPLE)? { //return Ok(Some(true)) //} //Ok(Some(true)) //} //} //pub const KEYMAP_ADD_SAMPLE: &'static [KeyBinding] = keymap!(AddSampleModal { //[Esc, NONE, "sampler/add/close", "close help dialog", |modal: &mut AddSampleModal|{ //modal.exit(); //Ok(true) //}], //[Up, NONE, "sampler/add/prev", "select previous entry", |modal: &mut AddSampleModal|{ //modal.prev(); //Ok(true) //}], //[Down, NONE, "sampler/add/next", "select next entry", |modal: &mut AddSampleModal|{ //modal.next(); //Ok(true) //}], //[Enter, NONE, "sampler/add/enter", "activate selected entry", |modal: &mut AddSampleModal|{ //if modal.pick()? { //modal.exit(); //} //Ok(true) //}], //[Char('p'), NONE, "sampler/add/preview", "preview selected entry", |modal: &mut AddSampleModal|{ //modal.try_preview()?; //Ok(true) //}] //}); //from_atom!("sampler" => |jack: &Jack, args| -> crate::Sampler { //let mut name = String::new(); //let mut dir = String::new(); //let mut samples = BTreeMap::new(); //atom!(atom in args { //Atom::Map(map) => { //if let Some(Atom::Str(n)) = map.get(&Atom::Key(":name")) { //name = String::from(*n); //} //if let Some(Atom::Str(n)) = map.get(&Atom::Key(":dir")) { //dir = String::from(*n); //} //}, //Atom::List(args) => match args.first() { //Some(Atom::Symbol("sample")) => { //let (midi, sample) = MidiSample::from_atom((jack, &dir), &args[1..])?; //if let Some(midi) = midi { //samples.insert(midi, sample); //} else { //panic!("sample without midi binding: {}", sample.read().unwrap().name); //} //}, //_ => panic!("unexpected in sampler {name}: {args:?}") //}, //_ => panic!("unexpected in sampler {name}: {atom:?}") //}); //Self::new(jack, &name) //}); //from_atom!("sample" => |(_jack, dir): (&Jack, &str), args| -> MidiSample { //let mut name = String::new(); //let mut file = String::new(); //let mut midi = None; //let mut start = 0usize; //atom!(atom in args { //Atom::Map(map) => { //if let Some(Atom::Str(n)) = map.get(&Atom::Key(":name")) { //name = String::from(*n); //} //if let Some(Atom::Str(f)) = map.get(&Atom::Key(":file")) { //file = String::from(*f); //} //if let Some(Atom::Int(i)) = map.get(&Atom::Key(":start")) { //start = *i as usize; //} //if let Some(Atom::Int(m)) = map.get(&Atom::Key(":midi")) { //midi = Some(u7::from(*m as u8)); //} //}, //_ => panic!("unexpected in sample {name}"), //}); //let (end, data) = Sample::read_data(&format!("{dir}/{file}"))?; //Ok((midi, Arc::new(RwLock::new(crate::Sample { //name, //start, //end, //channels: data, //rate: None, //gain: 1.0 //})))) //});