# launchy [![docs.rs](https://docs.rs/launchy/badge.svg)](https://docs.rs/launchy) [![crates.io](https://img.shields.io/crates/v/launchy)](https://crates.io/crates/launchy) [![License](https://img.shields.io/badge/license-MIT-blue)](https://github.com/kangalioo/launchy/blob/master/LICENSE) An exhaustive Rust API for the Novation Launchpad devices, optimized for maximum expressiveness and minimum boilerplate! --- Launchy is a library for the Novation Launchpad MIDI devices, for the Rust programming language. ## Features - the **Canvas API** provides a powerful and concise way to control your Launchpads, for games or small lightshows - the **direct Input/Output API** provides absolute control over your device and fine-grained access to the entire MIDI API of your device - it's possible to chain multiple Launchpads together and use them as if it was one single big device - optional support for [`embedded-graphics`](https://github.com/jamwaffles/embedded-graphics) - very modular design: it's very easy to add support for new devices, or to add new features to [`Canvas`] ## Supported devices - [ ] Launchpad - [x] Launchpad S - [x] Launchpad Mini - [x] Launchpad Control - [x] Launchpad Control XL - [ ] Launchpad Pro - [x] Launchpad MK2 - [ ] Launchpad X - [ ] Launchpad Mini MK3 - [ ] Launchpad Pro MK2 ## Canvas API Launchy provides a `Canvas` trait that allows you to abstract over the hardware-specific details of your Launchpad and write concise, performant and Launchpad-agnostic code. The `Canvas` API even allows you to chain multiple Launchpads together and use them as if they were a single device. See `CanvasLayout` for that. ## Direct Input/Output API In cases where you need direct access to your device's API, the abstraction provided by the `Canvas` API gets in your way. Say if you wanted to programmatically retrieve the firmware version of your Launchpad MK2: ```rust let input = launchy::mk2::Input::guess_polling()?; let mut output = launchy::mk2::Output::guess()?; output.request_version_inquiry()?; for msg in input.iter() { if let launchy::mk2::Message::VersionInquiry { firmware_version, .. } = msg { println!("The firmware version is {}", firmware_version); } } ``` ## Examples ### Satisfying pulse light effect ```rust // Setup devices let (mut canvas, poller) = launchy::CanvasLayout::new_polling(); canvas.add_by_guess_rotated::(0, 14, launchy::Rotation::Right)?; canvas.add_by_guess_rotated::(10, 18, launchy::Rotation::UpsideDown)?; canvas.add_by_guess_rotated::(2, 8, launchy::Rotation::Right)?; let mut canvas = canvas.into_padded(); // Do the actual animation for color in (0u64..).map(|f| Color::red_green_color(f as f32 / 60.0 / 2.5)) { for msg in poller.iter_for_millis(17).filter(|msg| msg.is_press()) { canvas[msg.pad()] = color * 60.0; } canvas.flush()?; for pad in canvas.iter() { let surrounding_color = pad.neighbors_5().iter() .map(|&p| canvas.get(p).unwrap_or(Color::BLACK)) .sum::() / 5.0 / 1.05; canvas[pad] = canvas[pad].mix(surrounding_color, 0.4); } } ``` ### Seamless text scrolling across multiple Launchpads (leveraging `embedded_graphics`) (This image shows the first three letters of the word "Hello") ```rust use embedded_graphics::{fonts::{Font6x8, Text}, prelude::{Drawable, Point}, style::TextStyle}; // Setup the Launchpad layout let mut canvas = launchy::CanvasLayout::new(|_msg| {}); canvas.add_by_guess_rotated::(0, 14, launchy::Rotation::Right)?; canvas.add_by_guess_rotated::(10, 18, launchy::Rotation::UpsideDown)?; canvas.add_by_guess_rotated::(2, 8, launchy::Rotation::Right)?; // Do the text scrolling let mut x_offset = 19; loop { canvas.clear(); let t = Text::new("Hello world! :)", Point::new(x_offset, 3)) .into_styled(TextStyle::new(Font6x8, Color::RED.into())) .draw(&mut canvas).unwrap(); canvas.flush()?; sleep(100); x_offset -= 1; } ``` ## Why not just use [launch-rs](https://github.com/jamesmunns/launch-rs)? - Last commit in 2017 - Only supports Launchpad MK2 - Only low-level access to the Launchpad is provided. There is no way to write high-level, concise interfacing code - Uses the [PortMidi](https://github.com/musitdev/portmidi-rs) crate which is not as actively developed as [midir](https://github.com/Boddlnagg/midir), which Launchy uses - Doesn't have any of the advanced features that Launchy provides