class GlimmerMetronome::View::AppView

Constants

COLOR_BEAT_DOWN
COLOR_BEAT_UP
FILE_SOUND_METRONOME_DOWN
FILE_SOUND_METRONOME_UP

Attributes

muted[RW]
muted?[RW]
stopped[RW]
stopped?[RW]

Public Instance Methods

beat(beat_index) click to toggle source
# File app/glimmer_metronome/view/app_view.rb, line 167
def beat(beat_index)
  canvas {
    layout_data {
      width_hint 50
      height_hint 50
    }
    
    background :red
    
    rectangle(0, 0, :default, :default, 36, 36) {
      background <= [@rhythm, "beats[#{beat_index}].up", on_read: ->(up) { up ? COLOR_BEAT_UP : COLOR_BEAT_DOWN}]
    }
    polygon(18, 16, 34, 25, 18, 34) {
      background <= [@rhythm, "beats[#{beat_index}].on", on_read: ->(on) { on ? :black : (@rhythm.beats[beat_index].up? ? COLOR_BEAT_UP : COLOR_BEAT_DOWN)}]
      background <= [@rhythm, "beats[#{beat_index}].up", on_read: ->(up) { @rhythm.beats[beat_index].on? ? :black : (up ? COLOR_BEAT_UP : COLOR_BEAT_DOWN)}]
    }
    
    on_mouse_up do
      if @rhythm.beats[beat_index].up?
        @rhythm.beats[beat_index].down!
      else
        @rhythm.beats[beat_index].up!
      end
    end
  }
end
build_audio_input(sound_file) click to toggle source
# File app/glimmer_metronome/view/app_view.rb, line 276
def build_audio_input(sound_file)
  # if running from packaged JAR, we get a uri:classloader sound_file
  if sound_file.start_with?('uri:classloader')
    jar_file_path = sound_file
    file_path = jar_file_path.sub(/^uri\:classloader\:/, '').sub(/^\/+/, '')
    require 'jruby'
    jcl = JRuby.runtime.jruby_class_loader
    resource = jcl.get_resource_as_stream(file_path)
    file_input_stream = resource.to_io.to_input_stream
    java.io.BufferedInputStream.new(file_input_stream)
  else
    java.io.File.new(sound_file)
  end
end
build_beats() click to toggle source
# File app/glimmer_metronome/view/app_view.rb, line 225
def build_beats
  stop_metronome!
  beat_container_layout_change = @rhythm.beat_count != @beats.count && (@rhythm.beat_count < 9 || @beats.count < 9)
  if @rhythm.beat_count > @beats.count
    index_start = @beats.count
    @beat_container.content {
      @beats += (@rhythm.beat_count - @beats.count).times.map do |n|
        beat(index_start + n)
      end
    }
  elsif @rhythm.beat_count < @beats.count
    first_index_to_dispose = -(@beats.count - @rhythm.beat_count)
    @beats[first_index_to_dispose..-1].each(&:dispose)
    @beats = @beats[0...first_index_to_dispose]
  end
  update_beat_container_layout if beat_container_layout_change
  start_metronome!
end
display_about_dialog() click to toggle source
# File app/glimmer_metronome/view/app_view.rb, line 291
def display_about_dialog
  dialog(body_root) {
    grid_layout(2, false) {
      margin_width 15
      margin_height 15
    }
    
    background :white
    image ICON
    text 'About'
    
    label {
      layout_data :center, :center, false, false
      background :white
      image ICON, height: 260
    }
    label {
      layout_data :fill, :fill, true, true
      background :white
      text "Glimmer Metronome #{VERSION}\n\n#{LICENSE}\n\nGlimmer Metronome icon made by Freepik from www.flaticon.com"
    }
  }.open
end
play_sound(sound_file) click to toggle source

Play sound with the Java Sound library

# File app/glimmer_metronome/view/app_view.rb, line 258
def play_sound(sound_file)
  return if @muted
  begin
    audio_input = build_audio_input(sound_file)
    audio_stream = AudioSystem.get_audio_input_stream(audio_input)
    clip = AudioSystem.clip
    clip.open(audio_stream)
    clip.start
  rescue => e
    puts e.full_message
  ensure
    Thread.new do
      sleep(0.01) while clip.running?
      clip.close
    end
  end
end
start_metronome!() click to toggle source
# File app/glimmer_metronome/view/app_view.rb, line 194
def start_metronome!
  self.stopped = false
  @thread ||= Thread.new do
    @rhythm.beat_count.times.cycle { |n|
      begin
        @rhythm.on_beat!(n)
      rescue => e
        puts e.full_message
      end
      sound_file = @rhythm.beats[n].up? ? FILE_SOUND_METRONOME_UP : FILE_SOUND_METRONOME_DOWN
      play_sound(sound_file)
      sleep(60.0/@rhythm.tempo.to_f)
    }
  end
end
stop_metronome!() click to toggle source
# File app/glimmer_metronome/view/app_view.rb, line 210
def stop_metronome!
  self.stopped = true
  @thread&.kill # not dangerous in this case and is useful to stop sleep
  @thread = nil
  @rhythm.off!
end
toggle_metronome!() click to toggle source
# File app/glimmer_metronome/view/app_view.rb, line 217
def toggle_metronome!
  if stopped?
    start_metronome!
  else
    stop_metronome!
  end
end
update_beat_container_layout() click to toggle source
# File app/glimmer_metronome/view/app_view.rb, line 244
def update_beat_container_layout
  @beat_container.content {
    if @rhythm.beat_count < 8
      grid_layout(@rhythm.beat_count, true)
    else
      grid_layout(8, true)
    end
  }
  body_root.layout(true, true)
  body_root.pack(true)
  body_root.center_within_display
end