mrjoy-launchpad 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
 - data/.gitignore +4 -0
 - data/.travis.yml +8 -0
 - data/Gemfile +6 -0
 - data/LICENSE +20 -0
 - data/README.rdoc +136 -0
 - data/Rakefile +10 -0
 - data/examples/binary_clock.rb +29 -0
 - data/examples/color_picker.rb +96 -0
 - data/examples/colors.rb +21 -0
 - data/examples/doodle.rb +68 -0
 - data/examples/double_buffering.rb +104 -0
 - data/examples/drawing_board.rb +25 -0
 - data/examples/feedback.rb +34 -0
 - data/examples/reset.rb +6 -0
 - data/launchpad.gemspec +34 -0
 - data/lib/launchpad.rb +34 -0
 - data/lib/launchpad/device.rb +574 -0
 - data/lib/launchpad/errors.rb +37 -0
 - data/lib/launchpad/interaction.rb +336 -0
 - data/lib/launchpad/logging.rb +27 -0
 - data/lib/launchpad/midi_codes.rb +53 -0
 - data/lib/launchpad/version.rb +3 -0
 - data/monitor.rb +88 -0
 - data/test/helper.rb +44 -0
 - data/test/test_device.rb +530 -0
 - data/test/test_interaction.rb +456 -0
 - data/testbed.rb +48 -0
 - metadata +146 -0
 
    
        checksums.yaml
    ADDED
    
    | 
         @@ -0,0 +1,7 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            ---
         
     | 
| 
      
 2 
     | 
    
         
            +
            SHA1:
         
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: f8c2eaea477fc7c3dd5587186a3ee2846705f14e
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: a5e36f0a19dd060bb7a48fd2414d4c05796981b8
         
     | 
| 
      
 5 
     | 
    
         
            +
            SHA512:
         
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: 4435b65556c71612909b4cd6ff980f506085d8a3fff825619d4e7ce72e9627b346bfae8f9865c86c9cb1c36580a37485991cc74331051aaf5ce8437d0b0062b5
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: c93a479be6b78023c09c9deedc2eb5818577a6cd7facb50cca3dd3fb77a6c5d8a5156ba312dc5dd30285a80d27354566318b027b3490cd32aea48ff1d9c99166
         
     | 
    
        data/.gitignore
    ADDED
    
    
    
        data/.travis.yml
    ADDED
    
    
    
        data/Gemfile
    ADDED
    
    
    
        data/LICENSE
    ADDED
    
    | 
         @@ -0,0 +1,20 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            Copyright (c) 2009 Thomas Jachmann
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            Permission is hereby granted, free of charge, to any person obtaining
         
     | 
| 
      
 4 
     | 
    
         
            +
            a copy of this software and associated documentation files (the
         
     | 
| 
      
 5 
     | 
    
         
            +
            "Software"), to deal in the Software without restriction, including
         
     | 
| 
      
 6 
     | 
    
         
            +
            without limitation the rights to use, copy, modify, merge, publish,
         
     | 
| 
      
 7 
     | 
    
         
            +
            distribute, sublicense, and/or sell copies of the Software, and to
         
     | 
| 
      
 8 
     | 
    
         
            +
            permit persons to whom the Software is furnished to do so, subject to
         
     | 
| 
      
 9 
     | 
    
         
            +
            the following conditions:
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            The above copyright notice and this permission notice shall be
         
     | 
| 
      
 12 
     | 
    
         
            +
            included in all copies or substantial portions of the Software.
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
            THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
         
     | 
| 
      
 15 
     | 
    
         
            +
            EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
         
     | 
| 
      
 16 
     | 
    
         
            +
            MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
         
     | 
| 
      
 17 
     | 
    
         
            +
            NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
         
     | 
| 
      
 18 
     | 
    
         
            +
            LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
         
     | 
| 
      
 19 
     | 
    
         
            +
            OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
         
     | 
| 
      
 20 
     | 
    
         
            +
            WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
         
     | 
    
        data/README.rdoc
    ADDED
    
    | 
         @@ -0,0 +1,136 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            = launchpad
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            {<img src="https://travis-ci.org/thomasjachmann/launchpad.png?branch=master" alt="Build Status" />}[https://travis-ci.org/thomasjachmann/launchpad]
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            This gem provides a ruby interface to access novation's launchpad programmatically. LEDs can be lighted and button presses can be responded to. Internally, launchpad's MIDI input/output is used to accomplish this.
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            The interfaces should be rather stable now (sorry, I changed quite a bit since the last release), so experiment with them and comment on their usability. This still is work in progress. If you need anything or think the interfaces could be improved in any way, please contact me.
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            Sometimes, the launchpad won't react to anything or react to/light up the wrong LEDs. Don't despair, just dis- and reconnect the thing. It seems that some (unexpected) MIDI signals make it hickup.
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            == This Fork
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            * Added ability to handle inputs without spawning a thread per input.
         
     | 
| 
      
 14 
     | 
    
         
            +
            * Modify to support for LaunchPad Mk 2.  Note that this breaks Mk 1 support!
         
     | 
| 
      
 15 
     | 
    
         
            +
                * Recognize identity string from this model.
         
     | 
| 
      
 16 
     | 
    
         
            +
                * Fix X/Y coordinates for buttons.
         
     | 
| 
      
 17 
     | 
    
         
            +
                * Add support for RGB colors.
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
            == More Info
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
            If you don't know what launchpad is, visit:
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
            * Novation's site at http://de.novationmusic.com/products/midi_controller/launchpad
         
     | 
| 
      
 25 
     | 
    
         
            +
            * my demo videos for this library at http://www.youtube.com/thomasjachmann
         
     | 
| 
      
 26 
     | 
    
         
            +
            * other demos on youtube http://www.youtube.com/results?search_query=novation+launchpad
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
            If you're into other languages or want to know what goes on behind the scenes MIDI wise, have a look at:
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
            * Novation's MIDI programmer's reference at {www.novationmusic.com/support/launchpad}[http://www.novationmusic.com/support/launchpad/] (bottom of the page)
         
     | 
| 
      
 31 
     | 
    
         
            +
            * Tobi Tobes' port of my gem to processing at http://github.com/rngtng/launchpad
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
            == Requirements
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
            * Roger B. Dannenberg's {portmidi library}[http://sourceforge.net/projects/portmedia/]
         
     | 
| 
      
 37 
     | 
    
         
            +
            * Jan Krutisch's {portmidi gem}[http://github.com/halfbyte/portmidi]
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
            == Compatibility
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
            The gem is known to be compatible with the following ruby versions:
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
            * MRI 1.8.7
         
     | 
| 
      
 45 
     | 
    
         
            +
            * MRI 1.9.3
         
     | 
| 
      
 46 
     | 
    
         
            +
            * MRI 2.0.0
         
     | 
| 
      
 47 
     | 
    
         
            +
            * MRI 2.2.2
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
            == Installation
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
            The gem is hosted on RubyGems[https://rubygems.org/], so in order to use it, you're gonna gem install it:
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
              gem install launchpad
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
            == Usage
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
            There are two main entry points:
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
      
 61 
     | 
    
         
            +
            * require 'launchpad/device', providing Launchpad::Device, which handles all the basic input/output stuff
         
     | 
| 
      
 62 
     | 
    
         
            +
            * require 'launchpad/interaction' or just 'launchpad', additionally providing Launchpad::Interaction, which lets you respond to actions (button presses/releases)
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
            This is a simple example (only requiring the device for output) that switches on all LEDs (for testing), resets the launchpad again and then lights the grid button at position 4/4 (from top left).
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
              require 'launchpad/device'
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
              device = Launchpad::Device.new
         
     | 
| 
      
 69 
     | 
    
         
            +
              device.test_leds
         
     | 
| 
      
 70 
     | 
    
         
            +
              sleep 1
         
     | 
| 
      
 71 
     | 
    
         
            +
              device.reset
         
     | 
| 
      
 72 
     | 
    
         
            +
              sleep 1
         
     | 
| 
      
 73 
     | 
    
         
            +
              device.change :grid, :x => 4, :y => 4, :red => :high, :green => :low
         
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
      
 75 
     | 
    
         
            +
            This is an interaction example lighting all grid buttons in red when pressed and keeping them lit.
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
      
 77 
     | 
    
         
            +
              require 'launchpad'
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
              interaction = Launchpad::Interaction.new
         
     | 
| 
      
 80 
     | 
    
         
            +
              interaction.response_to(:grid, :down) do |interaction, action|
         
     | 
| 
      
 81 
     | 
    
         
            +
                interaction.device.change(:grid, action.merge(:red => :high))
         
     | 
| 
      
 82 
     | 
    
         
            +
              end
         
     | 
| 
      
 83 
     | 
    
         
            +
              interaction.response_to(:mixer, :down) do |interaction, action|
         
     | 
| 
      
 84 
     | 
    
         
            +
                interaction.stop
         
     | 
| 
      
 85 
     | 
    
         
            +
              end
         
     | 
| 
      
 86 
     | 
    
         
            +
             
     | 
| 
      
 87 
     | 
    
         
            +
              interaction.start
         
     | 
| 
      
 88 
     | 
    
         
            +
             
     | 
| 
      
 89 
     | 
    
         
            +
             
     | 
| 
      
 90 
     | 
    
         
            +
            For more details, see the examples. examples/color_picker.rb is the most complex example with interaction.
         
     | 
| 
      
 91 
     | 
    
         
            +
             
     | 
| 
      
 92 
     | 
    
         
            +
             
     | 
| 
      
 93 
     | 
    
         
            +
            == Future plans
         
     | 
| 
      
 94 
     | 
    
         
            +
             
     | 
| 
      
 95 
     | 
    
         
            +
            * bitmap rendering
         
     | 
| 
      
 96 
     | 
    
         
            +
            * internal tracking of LED states for both buffers
         
     | 
| 
      
 97 
     | 
    
         
            +
             
     | 
| 
      
 98 
     | 
    
         
            +
             
     | 
| 
      
 99 
     | 
    
         
            +
            == Changelog
         
     | 
| 
      
 100 
     | 
    
         
            +
             
     | 
| 
      
 101 
     | 
    
         
            +
            === v.0.3.0
         
     | 
| 
      
 102 
     | 
    
         
            +
             
     | 
| 
      
 103 
     | 
    
         
            +
            * logging
         
     | 
| 
      
 104 
     | 
    
         
            +
            * reworked multi threading for action handling
         
     | 
| 
      
 105 
     | 
    
         
            +
            * compatibility with ruby 1.8.7 and 2.0.0
         
     | 
| 
      
 106 
     | 
    
         
            +
            * interaction responses for presses on single grid buttons/button areas/columns/rows
         
     | 
| 
      
 107 
     | 
    
         
            +
             
     | 
| 
      
 108 
     | 
    
         
            +
            === v.0.2.2
         
     | 
| 
      
 109 
     | 
    
         
            +
             
     | 
| 
      
 110 
     | 
    
         
            +
            * single threading fix: prevent ThreadError when Launchpad::Interaction#stop is called within an action response
         
     | 
| 
      
 111 
     | 
    
         
            +
             
     | 
| 
      
 112 
     | 
    
         
            +
            === v.0.2.1
         
     | 
| 
      
 113 
     | 
    
         
            +
             
     | 
| 
      
 114 
     | 
    
         
            +
            * Launchpad::Interaction#close now properly stops interaction first
         
     | 
| 
      
 115 
     | 
    
         
            +
            * multi threading: Launchpad::Interaction#start method can be called with :detached => true to allow calling thread to continue
         
     | 
| 
      
 116 
     | 
    
         
            +
             
     | 
| 
      
 117 
     | 
    
         
            +
            === v.0.2.0
         
     | 
| 
      
 118 
     | 
    
         
            +
             
     | 
| 
      
 119 
     | 
    
         
            +
            * double buffering (see Launchpad::Device#buffering_mode)
         
     | 
| 
      
 120 
     | 
    
         
            +
            * don't update grid button 0,0 before change_all (in order to reset rapid update pointer), use MIDI message without visual effect
         
     | 
| 
      
 121 
     | 
    
         
            +
            * (at least) doubled the speed of change_all by not sending each message individually but sending them in one go (as an array)
         
     | 
| 
      
 122 
     | 
    
         
            +
             
     | 
| 
      
 123 
     | 
    
         
            +
            === v0.1.1
         
     | 
| 
      
 124 
     | 
    
         
            +
             
     | 
| 
      
 125 
     | 
    
         
            +
            * ability to close device/interaction to free portmidi resources
         
     | 
| 
      
 126 
     | 
    
         
            +
            * ability to initialize devices using device ids as well as device names
         
     | 
| 
      
 127 
     | 
    
         
            +
            * complete documentation for http://rdoc.info/projects/thomasjachmann/launchpad
         
     | 
| 
      
 128 
     | 
    
         
            +
             
     | 
| 
      
 129 
     | 
    
         
            +
            === v0.1.0
         
     | 
| 
      
 130 
     | 
    
         
            +
             
     | 
| 
      
 131 
     | 
    
         
            +
            * first feature complete version with kinda stable API
         
     | 
| 
      
 132 
     | 
    
         
            +
             
     | 
| 
      
 133 
     | 
    
         
            +
             
     | 
| 
      
 134 
     | 
    
         
            +
            == Copyright
         
     | 
| 
      
 135 
     | 
    
         
            +
             
     | 
| 
      
 136 
     | 
    
         
            +
            Copyright (c) 2009 Thomas Jachmann. See LICENSE for details.
         
     | 
    
        data/Rakefile
    ADDED
    
    
| 
         @@ -0,0 +1,29 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'launchpad'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            device = Launchpad::Device.new
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            on = { :red => :high, :green => :off }
         
     | 
| 
      
 6 
     | 
    
         
            +
            off = { :red => :off, :green => :lo }
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            digit_map = [
         
     | 
| 
      
 9 
     | 
    
         
            +
              [off, off, off, off],
         
     | 
| 
      
 10 
     | 
    
         
            +
              [on , off, off, off],
         
     | 
| 
      
 11 
     | 
    
         
            +
              [off, on , off, off],
         
     | 
| 
      
 12 
     | 
    
         
            +
              [on , on , off, off],
         
     | 
| 
      
 13 
     | 
    
         
            +
              [off, off, on , off],
         
     | 
| 
      
 14 
     | 
    
         
            +
              [on , off, on , off],
         
     | 
| 
      
 15 
     | 
    
         
            +
              [off, on , on , off],
         
     | 
| 
      
 16 
     | 
    
         
            +
              [on , on , on , off],
         
     | 
| 
      
 17 
     | 
    
         
            +
              [off, off, off, on ],
         
     | 
| 
      
 18 
     | 
    
         
            +
              [on , off, off, on ]
         
     | 
| 
      
 19 
     | 
    
         
            +
            ]
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
            while true do
         
     | 
| 
      
 22 
     | 
    
         
            +
              Time.now.strftime('%H%M%S').split('').each_with_index do |digit, x|
         
     | 
| 
      
 23 
     | 
    
         
            +
                digit_map[digit.to_i].each_with_index do |color, y|
         
     | 
| 
      
 24 
     | 
    
         
            +
                  device.change :grid, color.merge(:x => x, :y => (7 - y))
         
     | 
| 
      
 25 
     | 
    
         
            +
                end
         
     | 
| 
      
 26 
     | 
    
         
            +
              end
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
              sleep 0.25
         
     | 
| 
      
 29 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,96 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'launchpad'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            interaction = Launchpad::Interaction.new
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            # build color arrays for color display views
         
     | 
| 
      
 6 
     | 
    
         
            +
            colors_single = [
         
     | 
| 
      
 7 
     | 
    
         
            +
              [ 0,  1,  2,  3,  0,  0,  0,  0],
         
     | 
| 
      
 8 
     | 
    
         
            +
              [16, 17, 18, 19,  0,  0,  0,  0],
         
     | 
| 
      
 9 
     | 
    
         
            +
              [32, 33, 34, 35,  0,  0,  0,  0],
         
     | 
| 
      
 10 
     | 
    
         
            +
              [48, 49, 50, 51,  0,  0,  0,  0],
         
     | 
| 
      
 11 
     | 
    
         
            +
              [0] * 8,
         
     | 
| 
      
 12 
     | 
    
         
            +
              [0] * 8,
         
     | 
| 
      
 13 
     | 
    
         
            +
              [0] * 8,
         
     | 
| 
      
 14 
     | 
    
         
            +
              [0] * 8,
         
     | 
| 
      
 15 
     | 
    
         
            +
              [0] * 8
         
     | 
| 
      
 16 
     | 
    
         
            +
            ]
         
     | 
| 
      
 17 
     | 
    
         
            +
            colors_double = [
         
     | 
| 
      
 18 
     | 
    
         
            +
              [ 0,  0,  1,  1,  2,  2,  3,  3],
         
     | 
| 
      
 19 
     | 
    
         
            +
              [ 0,  0,  1,  1,  2,  2,  3,  3],
         
     | 
| 
      
 20 
     | 
    
         
            +
              [16, 16, 17, 17, 18, 18, 19, 19],
         
     | 
| 
      
 21 
     | 
    
         
            +
              [16, 16, 17, 17, 18, 18, 19, 19],
         
     | 
| 
      
 22 
     | 
    
         
            +
              [32, 32, 33, 33, 34, 34, 35, 35],
         
     | 
| 
      
 23 
     | 
    
         
            +
              [32, 32, 33, 33, 34, 34, 35, 35],
         
     | 
| 
      
 24 
     | 
    
         
            +
              [48, 48, 49, 49, 50, 50, 51, 51],
         
     | 
| 
      
 25 
     | 
    
         
            +
              [48, 48, 49, 49, 50, 50, 51, 51],
         
     | 
| 
      
 26 
     | 
    
         
            +
              [0] * 8
         
     | 
| 
      
 27 
     | 
    
         
            +
            ]
         
     | 
| 
      
 28 
     | 
    
         
            +
            colors_mirrored = [
         
     | 
| 
      
 29 
     | 
    
         
            +
              [ 0,  1,  2,  3,  3,  2,  1,  0],
         
     | 
| 
      
 30 
     | 
    
         
            +
              [16, 17, 18, 19, 19, 18, 17, 16],
         
     | 
| 
      
 31 
     | 
    
         
            +
              [32, 33, 34, 35, 35, 34, 33, 32],
         
     | 
| 
      
 32 
     | 
    
         
            +
              [48, 49, 50, 51, 51, 50, 49, 48],
         
     | 
| 
      
 33 
     | 
    
         
            +
              [48, 49, 50, 51, 51, 50, 49, 48],
         
     | 
| 
      
 34 
     | 
    
         
            +
              [32, 33, 34, 35, 35, 34, 33, 32],
         
     | 
| 
      
 35 
     | 
    
         
            +
              [16, 17, 18, 19, 19, 18, 17, 16],
         
     | 
| 
      
 36 
     | 
    
         
            +
              [ 0,  1,  2,  3,  3,  2,  1,  0],
         
     | 
| 
      
 37 
     | 
    
         
            +
              [0] * 8
         
     | 
| 
      
 38 
     | 
    
         
            +
            ]
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
            # setup color display views
         
     | 
| 
      
 41 
     | 
    
         
            +
            def display_color_view(colors)
         
     | 
| 
      
 42 
     | 
    
         
            +
              lambda do |interaction, action|
         
     | 
| 
      
 43 
     | 
    
         
            +
                # set color
         
     | 
| 
      
 44 
     | 
    
         
            +
                interaction.device.change_all(colors)
         
     | 
| 
      
 45 
     | 
    
         
            +
                # register mute interactor on scene buttons
         
     | 
| 
      
 46 
     | 
    
         
            +
                interaction.response_to(%w(scene1 scene2 scene3 scene4 scene5 scene6 scene7 scene8), :down, :exclusive => true, &@mute)
         
     | 
| 
      
 47 
     | 
    
         
            +
              end
         
     | 
| 
      
 48 
     | 
    
         
            +
            end
         
     | 
| 
      
 49 
     | 
    
         
            +
            interaction.response_to(:up, :down, &display_color_view(colors_single + [48, 16, 16, 16]))
         
     | 
| 
      
 50 
     | 
    
         
            +
            interaction.response_to(:down, :down, &display_color_view(colors_double + [16, 48, 16, 16]))
         
     | 
| 
      
 51 
     | 
    
         
            +
            interaction.response_to(:left, :down, &display_color_view(colors_mirrored + [16, 16, 48, 16]))
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
            # setup color picker view
         
     | 
| 
      
 54 
     | 
    
         
            +
            def display_color(opts)
         
     | 
| 
      
 55 
     | 
    
         
            +
              lambda do |interaction, action|
         
     | 
| 
      
 56 
     | 
    
         
            +
                @red = opts[:red] if opts[:red]
         
     | 
| 
      
 57 
     | 
    
         
            +
                @green = opts[:green] if opts[:green]
         
     | 
| 
      
 58 
     | 
    
         
            +
                colors = [(@green * 16 + @red)] * 64
         
     | 
| 
      
 59 
     | 
    
         
            +
                scenes = [@red == 3 ? 51 : 3, @red == 2 ? 51 : 2, @red == 1 ? 51 : 1, @red == 0 ? 51 : 0, @green == 3 ? 51 : 48, @green == 2 ? 51 : 32, @green == 1 ? 51 : 16, @green == 0 ? 51 : 0]
         
     | 
| 
      
 60 
     | 
    
         
            +
                interaction.device.change_all(colors + scenes + [16, 16, 16, 48])
         
     | 
| 
      
 61 
     | 
    
         
            +
              end
         
     | 
| 
      
 62 
     | 
    
         
            +
            end
         
     | 
| 
      
 63 
     | 
    
         
            +
            interaction.response_to(:right, :down) do |interaction, action|
         
     | 
| 
      
 64 
     | 
    
         
            +
              @red = 0
         
     | 
| 
      
 65 
     | 
    
         
            +
              @green = 0
         
     | 
| 
      
 66 
     | 
    
         
            +
              # register color picker interactors on scene buttons
         
     | 
| 
      
 67 
     | 
    
         
            +
              interaction.response_to(:scene1, :down, :exclusive => true, &display_color(:red => 3))
         
     | 
| 
      
 68 
     | 
    
         
            +
              interaction.response_to(:scene2, :down, :exclusive => true, &display_color(:red => 2))
         
     | 
| 
      
 69 
     | 
    
         
            +
              interaction.response_to(:scene3, :down, :exclusive => true, &display_color(:red => 1))
         
     | 
| 
      
 70 
     | 
    
         
            +
              interaction.response_to(:scene4, :down, :exclusive => true, &display_color(:red => 0))
         
     | 
| 
      
 71 
     | 
    
         
            +
              interaction.response_to(:scene5, :down, :exclusive => true, &display_color(:green => 3))
         
     | 
| 
      
 72 
     | 
    
         
            +
              interaction.response_to(:scene6, :down, :exclusive => true, &display_color(:green => 2))
         
     | 
| 
      
 73 
     | 
    
         
            +
              interaction.response_to(:scene7, :down, :exclusive => true, &display_color(:green => 1))
         
     | 
| 
      
 74 
     | 
    
         
            +
              interaction.response_to(:scene8, :down, :exclusive => true, &display_color(:green => 0))
         
     | 
| 
      
 75 
     | 
    
         
            +
              # display color
         
     | 
| 
      
 76 
     | 
    
         
            +
              interaction.respond_to(:scene8, :down)
         
     | 
| 
      
 77 
     | 
    
         
            +
            end
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
            # mixer button terminates interaction on button up
         
     | 
| 
      
 80 
     | 
    
         
            +
            interaction.response_to(:mixer) do |interaction, action|
         
     | 
| 
      
 81 
     | 
    
         
            +
              interaction.device.change(:mixer, :red => action[:state] == :down ? :hi : :off)
         
     | 
| 
      
 82 
     | 
    
         
            +
              interaction.stop if action[:state] == :up
         
     | 
| 
      
 83 
     | 
    
         
            +
            end
         
     | 
| 
      
 84 
     | 
    
         
            +
             
     | 
| 
      
 85 
     | 
    
         
            +
            # setup mute display interactors on all unused buttons
         
     | 
| 
      
 86 
     | 
    
         
            +
            @mute = display_color_view([0] * 72 + [16, 16, 16, 16])
         
     | 
| 
      
 87 
     | 
    
         
            +
            interaction.response_to(%w(session user1 user2 grid), :down, &@mute)
         
     | 
| 
      
 88 
     | 
    
         
            +
             
     | 
| 
      
 89 
     | 
    
         
            +
            # display mute view
         
     | 
| 
      
 90 
     | 
    
         
            +
            interaction.respond_to(:session, :down)
         
     | 
| 
      
 91 
     | 
    
         
            +
             
     | 
| 
      
 92 
     | 
    
         
            +
            # start interacting
         
     | 
| 
      
 93 
     | 
    
         
            +
            interaction.start
         
     | 
| 
      
 94 
     | 
    
         
            +
             
     | 
| 
      
 95 
     | 
    
         
            +
            # sleep so that the messages can be sent before the program terminates
         
     | 
| 
      
 96 
     | 
    
         
            +
            sleep 0.1
         
     | 
    
        data/examples/colors.rb
    ADDED
    
    | 
         @@ -0,0 +1,21 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'launchpad'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            device = Launchpad::Device.new(:input => false, :output => true)
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            pos_x = pos_y = 0
         
     | 
| 
      
 6 
     | 
    
         
            +
            4.times do |red|
         
     | 
| 
      
 7 
     | 
    
         
            +
              4.times do |green|
         
     | 
| 
      
 8 
     | 
    
         
            +
                device.change :grid, :x => pos_x, :y => pos_y, :red => red, :green => green
         
     | 
| 
      
 9 
     | 
    
         
            +
                device.change :grid, :x => 7 - pos_x, :y => pos_y, :red => red, :green => green
         
     | 
| 
      
 10 
     | 
    
         
            +
                device.change :grid, :x => pos_x, :y => 7 - pos_y, :red => red, :green => green
         
     | 
| 
      
 11 
     | 
    
         
            +
                device.change :grid, :x => 7 - pos_x, :y => 7 - pos_y, :red => red, :green => green
         
     | 
| 
      
 12 
     | 
    
         
            +
                pos_y += 1
         
     | 
| 
      
 13 
     | 
    
         
            +
                # sleep, otherwise the connection drops some messages - WTF?
         
     | 
| 
      
 14 
     | 
    
         
            +
                sleep 0.01
         
     | 
| 
      
 15 
     | 
    
         
            +
              end
         
     | 
| 
      
 16 
     | 
    
         
            +
              pos_x += 1
         
     | 
| 
      
 17 
     | 
    
         
            +
              pos_y = 0
         
     | 
| 
      
 18 
     | 
    
         
            +
            end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
            # sleep so that the messages can be sent before the program terminates
         
     | 
| 
      
 21 
     | 
    
         
            +
            sleep 0.1
         
     | 
    
        data/examples/doodle.rb
    ADDED
    
    | 
         @@ -0,0 +1,68 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'launchpad'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            interaction = Launchpad::Interaction.new
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            current_color = {
         
     | 
| 
      
 6 
     | 
    
         
            +
              :red    => :hi,
         
     | 
| 
      
 7 
     | 
    
         
            +
              :green  => :hi,
         
     | 
| 
      
 8 
     | 
    
         
            +
              :mode   => :normal
         
     | 
| 
      
 9 
     | 
    
         
            +
            }
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            def update_scene_buttons(d, color)
         
     | 
| 
      
 12 
     | 
    
         
            +
              on = {:red => :hi, :green => :hi}
         
     | 
| 
      
 13 
     | 
    
         
            +
              d.change(:scene1, color[:red] == :hi ? on : {:red => :hi})
         
     | 
| 
      
 14 
     | 
    
         
            +
              d.change(:scene2, color[:red] == :med ? on : {:red => :med})
         
     | 
| 
      
 15 
     | 
    
         
            +
              d.change(:scene3, color[:red] == :lo ? on : {:red => :lo})
         
     | 
| 
      
 16 
     | 
    
         
            +
              d.change(:scene4, color[:red] == :off ? on : {:red => :off})
         
     | 
| 
      
 17 
     | 
    
         
            +
              d.change(:scene5, color[:green] == :hi ? on : {:green => :hi})
         
     | 
| 
      
 18 
     | 
    
         
            +
              d.change(:scene6, color[:green] == :med ? on : {:green => :med})
         
     | 
| 
      
 19 
     | 
    
         
            +
              d.change(:scene7, color[:green] == :lo ? on : {:green => :lo})
         
     | 
| 
      
 20 
     | 
    
         
            +
              d.change(:scene8, color[:green] == :off ? on : {:green => :off})
         
     | 
| 
      
 21 
     | 
    
         
            +
              d.change(:user1, :green => color[:mode] == :normal ? :lo : :hi, :mode => :flashing)
         
     | 
| 
      
 22 
     | 
    
         
            +
              d.change(:user2, :green => color[:mode] == :normal ? :hi : :lo)
         
     | 
| 
      
 23 
     | 
    
         
            +
            end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
            def choose_color(color, opts)
         
     | 
| 
      
 26 
     | 
    
         
            +
              lambda do |interaction, action|
         
     | 
| 
      
 27 
     | 
    
         
            +
                color.update(opts)
         
     | 
| 
      
 28 
     | 
    
         
            +
                update_scene_buttons(interaction.device, color)
         
     | 
| 
      
 29 
     | 
    
         
            +
              end
         
     | 
| 
      
 30 
     | 
    
         
            +
            end
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
            # register color picker interactors on scene buttons
         
     | 
| 
      
 33 
     | 
    
         
            +
            interaction.response_to(:scene1, :down, &choose_color(current_color, :red => :hi))
         
     | 
| 
      
 34 
     | 
    
         
            +
            interaction.response_to(:scene2, :down, &choose_color(current_color, :red => :med))
         
     | 
| 
      
 35 
     | 
    
         
            +
            interaction.response_to(:scene3, :down, &choose_color(current_color, :red => :lo))
         
     | 
| 
      
 36 
     | 
    
         
            +
            interaction.response_to(:scene4, :down, &choose_color(current_color, :red => :off))
         
     | 
| 
      
 37 
     | 
    
         
            +
            interaction.response_to(:scene5, :down, &choose_color(current_color, :green => :hi))
         
     | 
| 
      
 38 
     | 
    
         
            +
            interaction.response_to(:scene6, :down, &choose_color(current_color, :green => :med))
         
     | 
| 
      
 39 
     | 
    
         
            +
            interaction.response_to(:scene7, :down, &choose_color(current_color, :green => :lo))
         
     | 
| 
      
 40 
     | 
    
         
            +
            interaction.response_to(:scene8, :down, &choose_color(current_color, :green => :off))
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
            # register mode picker interactors on user buttons
         
     | 
| 
      
 43 
     | 
    
         
            +
            interaction.response_to(:user1, :down, &choose_color(current_color, :mode => :flashing))
         
     | 
| 
      
 44 
     | 
    
         
            +
            interaction.response_to(:user2, :down, &choose_color(current_color, :mode => :normal))
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
            # update scene buttons and start flashing
         
     | 
| 
      
 47 
     | 
    
         
            +
            update_scene_buttons(interaction.device, current_color)
         
     | 
| 
      
 48 
     | 
    
         
            +
            interaction.device.flashing_auto
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
            # feedback for grid buttons
         
     | 
| 
      
 51 
     | 
    
         
            +
            interaction.response_to(:grid, :down) do |interaction, action|
         
     | 
| 
      
 52 
     | 
    
         
            +
              #coord = 16 * action[:y] + action[:x]
         
     | 
| 
      
 53 
     | 
    
         
            +
              #brightness = flags[coord] ? :off : :hi
         
     | 
| 
      
 54 
     | 
    
         
            +
              #flags[coord] = !flags[coord]
         
     | 
| 
      
 55 
     | 
    
         
            +
              interaction.device.change(:grid, action.merge(current_color))
         
     | 
| 
      
 56 
     | 
    
         
            +
            end
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
            # mixer button terminates interaction on button up
         
     | 
| 
      
 59 
     | 
    
         
            +
            interaction.response_to(:mixer) do |interaction, action|
         
     | 
| 
      
 60 
     | 
    
         
            +
              interaction.device.change(:mixer, :red => action[:state] == :down ? :hi : :off)
         
     | 
| 
      
 61 
     | 
    
         
            +
              interaction.stop if action[:state] == :up
         
     | 
| 
      
 62 
     | 
    
         
            +
            end
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
            # start interacting
         
     | 
| 
      
 65 
     | 
    
         
            +
            interaction.start
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
            # sleep so that the messages can be sent before the program terminates
         
     | 
| 
      
 68 
     | 
    
         
            +
            sleep 0.1
         
     | 
| 
         @@ -0,0 +1,104 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'launchpad'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            interaction = Launchpad::Interaction.new
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            # store and change button states, ugly but well...
         
     | 
| 
      
 6 
     | 
    
         
            +
            @button_states = [
         
     | 
| 
      
 7 
     | 
    
         
            +
              [false, false, false, false, false, false, false, false],
         
     | 
| 
      
 8 
     | 
    
         
            +
              [false, false, false, false, false, false, false, false],
         
     | 
| 
      
 9 
     | 
    
         
            +
              [[false, false], [false, false], [false, false], [false, false], [false, false], [false, false], [false, false], [false, false]],
         
     | 
| 
      
 10 
     | 
    
         
            +
              [[false, false], [false, false], [false, false], [false, false], [false, false], [false, false], [false, false], [false, false]],
         
     | 
| 
      
 11 
     | 
    
         
            +
              [[false, false], [false, false], [false, false], [false, false], [false, false], [false, false], [false, false], [false, false]],
         
     | 
| 
      
 12 
     | 
    
         
            +
              [[false, false], [false, false], [false, false], [false, false], [false, false], [false, false], [false, false], [false, false]],
         
     | 
| 
      
 13 
     | 
    
         
            +
              [[false, false], [false, false], [false, false], [false, false], [false, false], [false, false], [false, false], [false, false]],
         
     | 
| 
      
 14 
     | 
    
         
            +
              [[false, false], [false, false], [false, false], [false, false], [false, false], [false, false], [false, false], [false, false]]
         
     | 
| 
      
 15 
     | 
    
         
            +
            ]
         
     | 
| 
      
 16 
     | 
    
         
            +
            def change_button_state(action)
         
     | 
| 
      
 17 
     | 
    
         
            +
              if action[:y] > 1
         
     | 
| 
      
 18 
     | 
    
         
            +
                which = @active_buffer_button == :user2 ? 1 : 0
         
     | 
| 
      
 19 
     | 
    
         
            +
                @button_states[action[:y]][action[:x]][which] = !@button_states[action[:y]][action[:x]][which]
         
     | 
| 
      
 20 
     | 
    
         
            +
              else
         
     | 
| 
      
 21 
     | 
    
         
            +
                @button_states[action[:y]][action[:x]] = !@button_states[action[:y]][action[:x]]
         
     | 
| 
      
 22 
     | 
    
         
            +
              end
         
     | 
| 
      
 23 
     | 
    
         
            +
            end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
            # setup grid buttons to:
         
     | 
| 
      
 26 
     | 
    
         
            +
            # * set LEDs in normal mode on the first row
         
     | 
| 
      
 27 
     | 
    
         
            +
            # * set LEDs in flashing mode on the second row
         
     | 
| 
      
 28 
     | 
    
         
            +
            # * set LEDs in buffering mode on all other rows
         
     | 
| 
      
 29 
     | 
    
         
            +
            interaction.response_to(:grid, :down) do |interaction, action|
         
     | 
| 
      
 30 
     | 
    
         
            +
              color = change_button_state(action) ? @color : {}
         
     | 
| 
      
 31 
     | 
    
         
            +
              case action[:y]
         
     | 
| 
      
 32 
     | 
    
         
            +
              when 0
         
     | 
| 
      
 33 
     | 
    
         
            +
                interaction.device.change(:grid, action.merge(color))
         
     | 
| 
      
 34 
     | 
    
         
            +
              when 1
         
     | 
| 
      
 35 
     | 
    
         
            +
                interaction.device.buffering_mode(:flashing => false, :display_buffer => 1, :update_buffer => 0)
         
     | 
| 
      
 36 
     | 
    
         
            +
                interaction.device.change(:grid, action.merge(color).merge(:mode => :flashing))
         
     | 
| 
      
 37 
     | 
    
         
            +
                interaction.respond_to(@active_buffer_button, :down)
         
     | 
| 
      
 38 
     | 
    
         
            +
              else
         
     | 
| 
      
 39 
     | 
    
         
            +
                interaction.device.change(:grid, action.merge(color).merge(:mode => :buffering))
         
     | 
| 
      
 40 
     | 
    
         
            +
              end
         
     | 
| 
      
 41 
     | 
    
         
            +
            end
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
            # green feedback for buffer buttons
         
     | 
| 
      
 44 
     | 
    
         
            +
            interaction.response_to([:session, :user1, :user2], :down) do |interaction, action|
         
     | 
| 
      
 45 
     | 
    
         
            +
              case @active_buffer_button = action[:type]
         
     | 
| 
      
 46 
     | 
    
         
            +
              when :session
         
     | 
| 
      
 47 
     | 
    
         
            +
                interaction.device.buffering_mode(:flashing => true)
         
     | 
| 
      
 48 
     | 
    
         
            +
              when :user1
         
     | 
| 
      
 49 
     | 
    
         
            +
                interaction.device.buffering_mode(:display_buffer => 0, :update_buffer => 0)
         
     | 
| 
      
 50 
     | 
    
         
            +
              when :user2
         
     | 
| 
      
 51 
     | 
    
         
            +
                interaction.device.buffering_mode(:display_buffer => 1, :update_buffer => 1)
         
     | 
| 
      
 52 
     | 
    
         
            +
              end
         
     | 
| 
      
 53 
     | 
    
         
            +
              interaction.device.change(:session, :red => @active_buffer_button == :session ? :hi : :lo, :green => @active_buffer_button == :session ? :hi : :lo)
         
     | 
| 
      
 54 
     | 
    
         
            +
              interaction.device.change(:user1, :red => @active_buffer_button == :user1 ? :hi : :lo, :green => @active_buffer_button == :user1 ? :hi : :lo)
         
     | 
| 
      
 55 
     | 
    
         
            +
              interaction.device.change(:user2, :red => @active_buffer_button == :user2 ? :hi : :lo, :green => @active_buffer_button == :user2 ? :hi : :lo)
         
     | 
| 
      
 56 
     | 
    
         
            +
            end
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
            # setup color picker
         
     | 
| 
      
 59 
     | 
    
         
            +
            def display_color(opts)
         
     | 
| 
      
 60 
     | 
    
         
            +
              lambda do |interaction, action|
         
     | 
| 
      
 61 
     | 
    
         
            +
                @red = opts[:red] if opts[:red]
         
     | 
| 
      
 62 
     | 
    
         
            +
                @green = opts[:green] if opts[:green]
         
     | 
| 
      
 63 
     | 
    
         
            +
                if @red == 0 && @green == 0
         
     | 
| 
      
 64 
     | 
    
         
            +
                  @red = 1 if opts[:red]
         
     | 
| 
      
 65 
     | 
    
         
            +
                  @green = 1 if opts[:green]
         
     | 
| 
      
 66 
     | 
    
         
            +
                end
         
     | 
| 
      
 67 
     | 
    
         
            +
                @color = {:red => @red, :green => @green}
         
     | 
| 
      
 68 
     | 
    
         
            +
                on = {:red => 3, :green => 3}
         
     | 
| 
      
 69 
     | 
    
         
            +
                interaction.device.change(:scene1, @red == 3 ? on : {:red => 3})
         
     | 
| 
      
 70 
     | 
    
         
            +
                interaction.device.change(:scene2, @red == 2 ? on : {:red => 2})
         
     | 
| 
      
 71 
     | 
    
         
            +
                interaction.device.change(:scene3, @red == 1 ? on : {:red => 1})
         
     | 
| 
      
 72 
     | 
    
         
            +
                interaction.device.change(:scene4, @red == 0 ? on : {:red => 0})
         
     | 
| 
      
 73 
     | 
    
         
            +
                interaction.device.change(:scene5, @green == 3 ? on : {:green => 3})
         
     | 
| 
      
 74 
     | 
    
         
            +
                interaction.device.change(:scene6, @green == 2 ? on : {:green => 2})
         
     | 
| 
      
 75 
     | 
    
         
            +
                interaction.device.change(:scene7, @green == 1 ? on : {:green => 1})
         
     | 
| 
      
 76 
     | 
    
         
            +
                interaction.device.change(:scene8, @green == 0 ? on : {:green => 0})
         
     | 
| 
      
 77 
     | 
    
         
            +
              end
         
     | 
| 
      
 78 
     | 
    
         
            +
            end
         
     | 
| 
      
 79 
     | 
    
         
            +
            # register color picker interactors on scene buttons
         
     | 
| 
      
 80 
     | 
    
         
            +
            interaction.response_to(:scene1, :down, :exclusive => true, &display_color(:red => 3))
         
     | 
| 
      
 81 
     | 
    
         
            +
            interaction.response_to(:scene2, :down, :exclusive => true, &display_color(:red => 2))
         
     | 
| 
      
 82 
     | 
    
         
            +
            interaction.response_to(:scene3, :down, :exclusive => true, &display_color(:red => 1))
         
     | 
| 
      
 83 
     | 
    
         
            +
            interaction.response_to(:scene4, :down, :exclusive => true, &display_color(:red => 0))
         
     | 
| 
      
 84 
     | 
    
         
            +
            interaction.response_to(:scene5, :down, :exclusive => true, &display_color(:green => 3))
         
     | 
| 
      
 85 
     | 
    
         
            +
            interaction.response_to(:scene6, :down, :exclusive => true, &display_color(:green => 2))
         
     | 
| 
      
 86 
     | 
    
         
            +
            interaction.response_to(:scene7, :down, :exclusive => true, &display_color(:green => 1))
         
     | 
| 
      
 87 
     | 
    
         
            +
            interaction.response_to(:scene8, :down, :exclusive => true, &display_color(:green => 0))
         
     | 
| 
      
 88 
     | 
    
         
            +
            # pick green
         
     | 
| 
      
 89 
     | 
    
         
            +
            interaction.respond_to(:scene5, :down)
         
     | 
| 
      
 90 
     | 
    
         
            +
             
     | 
| 
      
 91 
     | 
    
         
            +
            # mixer button terminates interaction on button up
         
     | 
| 
      
 92 
     | 
    
         
            +
            interaction.response_to(:mixer) do |interaction, action|
         
     | 
| 
      
 93 
     | 
    
         
            +
              interaction.device.change(:mixer, :red => action[:state] == :down ? :hi : :off)
         
     | 
| 
      
 94 
     | 
    
         
            +
              interaction.stop if action[:state] == :up
         
     | 
| 
      
 95 
     | 
    
         
            +
            end
         
     | 
| 
      
 96 
     | 
    
         
            +
             
     | 
| 
      
 97 
     | 
    
         
            +
            # start in auto flashing mode
         
     | 
| 
      
 98 
     | 
    
         
            +
            interaction.respond_to(:session, :down)
         
     | 
| 
      
 99 
     | 
    
         
            +
             
     | 
| 
      
 100 
     | 
    
         
            +
            # start interacting
         
     | 
| 
      
 101 
     | 
    
         
            +
            interaction.start
         
     | 
| 
      
 102 
     | 
    
         
            +
             
     | 
| 
      
 103 
     | 
    
         
            +
            # sleep so that the messages can be sent before the program terminates
         
     | 
| 
      
 104 
     | 
    
         
            +
            sleep 0.1
         
     |