Permalink
Browse files

music-browser

  • Loading branch information...
1 parent 095db40 commit 67d1b9d9854f39e59a60333d4f7fecddc72f9272 @lljk committed Jun 26, 2011
Showing with 189 additions and 0 deletions.
  1. +9 −0 music-browser/README
  2. +180 −0 music-browser/browser.rb
  3. BIN music-browser/no_cover.jpg
@@ -0,0 +1,9 @@
+ this is a simple music directory browser. !! CHANGE THE SECOND TO LAST LINE OF CODE TO POINT TO YOUR MUSIC DIRECTORY !! - it points to mine, and that won't do you much good!
+
+ my default background is black, so forgive me if it looks a little funny ;)
+
+ it will look in a given directory for image files, and use the first one it finds as the image to represent the directory. you'll also need a jpg image file called 'no_cover.jpg' in the directory the script is running from. the 'up' button on the left side moves you up one directory in the structure. the directories and music files (.mp3, .ogg, .flac, .wav) within the current directory are shown on the right side - first the directories, and then the files.
+
+ clicking on files shown on the right side will select them, clicking them again will unselect them. clicking on the directory image shown on the left side will select all of the files shown on the right. once some files are selected, you can send a signal to the Shoes main app - in this example to either append or prepend the tracks to an imaginary playlist - with the buttons ' list << ' and ' >> list ' on the bottom of the right side.
+
+ my music directory is set up something like this: tunes/hendrix/electric ladyland - and the browser will work best with this structure, but any should be fine (i think!)
@@ -0,0 +1,180 @@
+require 'observer'
+
+class BrowserListManager < Shoes::Widget
+ include Observable
+
+ def initialize(array, selected=[])
+ @selected = selected
+ @s = stack{
+ array.each{|item|
+ if @selected.include?(item)
+ cell = link(File.basename(item), stroke: yellow, underline: "none")
+ else
+ cell = link(File.basename(item), stroke: gray, underline: "none")
+ end
+ cell.hover{cell.style(fill: blue)}
+ cell.leave{cell.style(fill: black)}
+ cell.click{
+ if @selected.include?(item)
+ cell.style(stroke: gray)
+ changed
+ notify_observers("unselect:#{item}")
+ else
+ cell.style(stroke: yellow)
+ changed
+ notify_observers(item)
+ end
+ }
+ para cell
+ }
+ }
+ end
+
+end #class ListManager
+
+
+class DirBrowser < Shoes::Widget
+ include Observable
+
+ def initialize(path)
+ @homedir = File.expand_path(File.dirname(__FILE__))
+ @leftpane = stack width: 200, height: 500
+ @rightpane = flow width: -205, height: 500, scroll: true
+ self.pathscan(path)
+ end
+
+ def pathscan(path)
+ @leftpane.clear
+ @rightpane.clear
+ okfiles = %W[.mp3 .flac .ogg .wav]
+ dirs = []
+ files = []
+ Dir.open(path){|dir|
+ for entry in dir
+ next if entry == '.'
+ next if entry == '..'
+ item = path + File::Separator + entry
+ if File.directory?(item)
+ dirs << item
+ else
+ okfiles.each{|ok| files << item if item.downcase.include?(ok)}
+ end
+ end
+ }
+ self.leftSide(path)
+ @dirs = dirs.sort
+ self.rightSideDirs(@dirs) if @dirs[0] != nil
+ @files = files.sort
+ @selected = []
+ self.rightSideFiles(@files, @selected) if @files[0] != nil
+ end
+
+ def leftSide(path)
+ self.getImage(path)
+ @leftpane.append{
+ para path, stroke: gray, width: 180, align: "center"
+ }
+ @leftpane.append{img = image(@img)
+ img.style(width: 180, height: 180, displace_left: 10, top: 140)
+ img.click{
+ if @files[0] != nil
+ @files.each{|f| @selected << f}
+ self.rightSideFiles(@files, @selected)
+ end
+ }
+ }
+ @leftpane.append{btn = button("up"){
+ new = File.split(path)[0]
+ self.pathscan(new)
+ }
+ btn.style(top: 420, displace_left: 80)
+ }
+ end
+
+ def rightSideDirs(dirs)
+ dirs.each{|d|
+ self.getImage(d)
+ @rightpane.append{
+ s = stack width:200 do
+ i = image(@img)
+ i.style(width: 190, height: 190, align: "center")
+ para File.basename(d), stroke: gray, align: "center"
+ end
+ s.click{self.pathscan(d)}
+ }
+ }
+ end
+
+ def rightSideFiles(files, selected)
+ @rightpane.clear
+ @rightpane.append{
+ th = (parent.height * 0.9).round.to_i
+ bh = (parent.height * 0.1).round.to_i
+ top = stack width: 1.0, height: th, scroll: true
+ bottom = stack width: 1.0, height: bh, stroke: gray
+
+ top.append{
+ lm = browser_list_manager(files, selected)
+ lm.add_observer(self)
+ }
+
+ bottom.append{
+ btns = flow{
+ button(">> list"){
+ changed
+ notify_observers("DB:prepend:#{@selected}")
+ @selected = []
+ self.rightSideFiles(files, @selected)
+ }
+ button("list <<"){
+ changed
+ notify_observers("DB:append:#{@selected}")
+ @selected = []
+ self.rightSideFiles(files, @selected)
+ }
+ }
+ btns.style(top: 10, left: 20)
+ }
+ }
+ end
+
+ def getImage(path)
+ Dir.chdir(path)
+ imgfiles = Dir['*.{jpg,JPG,png,PNG,gif,GIF}']
+ imgfile = imgfiles[0]
+ imgfile = "nofile.jpg" if imgfile == nil
+ if File.exist?(imgfile)
+ @img = path + File::Separator + imgfile
+ else
+ @img = @homedir + File::Separator + "no_cover.jpg"
+ end
+ end
+
+ def update(message)
+ if message.include?("unselect")
+ index = message.split(":")[-1]
+ @selected.delete(index)
+ else
+ @selected << message
+ end
+ end
+
+end #class DirBrowser
+
+
+Shoes.app title: "main"do
+
+ def update(message)
+ para message, stroke: gray
+ end
+
+ def browser(parent, basedir)
+ window width: 820 do
+ b = dir_browser(basedir)
+ b.add_observer(parent)
+ end
+ end
+
+ button("browser"){browser(self, "/home/jk/tunes")} ## CHANGE THIS!
+
+end #Shoes.app
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 67d1b9d

Please sign in to comment.