Skip to content

Instantly share code, notes, and snippets.

@qwzybug
Created February 25, 2009 23:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save qwzybug/70524 to your computer and use it in GitHub Desktop.
Save qwzybug/70524 to your computer and use it in GitHub Desktop.
Refactoring a Shoes widget. Needs midiator gem.
class Piano < Widget
def initialize opts = {}, &action
opts = {:width => 700, :height => 100}.merge opts
@action = action
key_width = opts[:width] / 52.0
ivory = {:bottom => 0, :width => key_width.round, :height => opts[:height] * 2 / 5}
ebony = {:top => 0, :width => (key_width * 2 / 3).round, :height => opts[:height] * 3 / 5}
last_x = -key_width
stack(opts) {
background white; stroke black
(21..109).each do |note|
x = last_x.round
if [0, 2, 4, 5, 7, 9, 11].include? note % 12
last_x += key_width
midi_button ivory.merge(:left => x), gray(0,0), note
line x, 0, x, opts[:height]
else
midi_button ebony.merge(:left => x + ebony[:width]), black, note
end
end
}
@midi = MIDIator::Interface.new
@midi.autodetect_driver
end
def play note
@midi.play(note, 0.1, 2, 100)
@action.call(note) if @action
end
def midi_button rect, color, note
stack(rect) { background color; click { play note } }
end
end
class Keyboard < Widget
attr_accessor :target
def initialize opts = {}
@width, @height = opts[:width], opts[:height]
white_notes = [0, 2, 4, 5, 7, 9, 11]
key_width = @width / 52.0
last_x = -key_width
white_keys = stack(:top => 0, :left => 0, :width => @width, :height => @height)
black_keys = stack(:top => 0, :left => 0, :width => @width, :height => @height)
stroke black
flow(:width => @width, :height => @height) {
(21..109).each do |number|
scale_note = number % 12
if white_notes.include? scale_note
last_x += key_width
x, y, w, h, c, s = last_x.to_i, 0, key_width.to_i, @height, white, white_keys
line last_x.to_i, 0, last_x.to_i, @height
else
x, y, w, h, c, s = (last_x + key_width * 2 / 3).to_i, 0,
(key_width * 2 / 3).to_i, @height * 2 / 3,
black, black_keys
end
s.append { midi_button({:left => x, :top => y, :width => w, :height => h}, c, number) }
end
}
@midi = MIDIator::Interface.new
@midi.autodetect_driver
end
def play_note number
@midi.play(number, 0.1, 2, 100)
end
def midi_button(r, c, n)
stack(r) { background c; click {|button, x, y| play_note(n); target.call(n) if target} }
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment