#!/usr/bin/env ruby #$: << File.expand_path(File.dirname(FILE) + “/../lib”)) #require 'libgruxclient' require 'gtk2' require 'xmmsclient' require 'xmmsclient_glib' class Grux end class Grux::ClientWin < Gtk::VBox def initialize super @server = Xmms::Client.new( 'Grux' ) @cntrlBtnBox = Gtk::HButtonBox.new @statusLblBox = Gtk::VBox.new @playlistViewWin = Gtk::ScrolledWindow.new @playlistTextRenderer = Gtk::CellRendererText.new @playlistView = Gtk::TreeView.new @playlistList = Gtk::ListStore.new( String, String ) @playlistColumns = [ 'artist', 'title' ] @playlistColumns.each_with_index do |tag, index| @playlistView.append_column Gtk::TreeViewColumn.new( tag, @playlistTextRenderer, :text => index ) end @playlistViewWin << @playlistView @statusBar = Gtk::Statusbar.new @cntrlbtns = [ @playBtn = Gtk::Button.new('_Play/Pause'), @stopBtn = Gtk::Button.new('_Stop'), @nextBtn = Gtk::Button.new('_Next'), @prevBtn = Gtk::Button.new('Pre_vious'), @rndmBtn = Gtk::Button.new('_Random'), @rptBtn = Gtk::Button.new('Re_peat') ] @statusLbls = [ @stateLbl = Gtk::Label.new, @repeatLbl = Gtk::Label.new, @playbackLbl = Gtk::Label.new, @nextSongLbl = Gtk::Label.new ] @cntrlbtns.each do |button| @cntrlBtnBox.pack_start button end @statusLbls.each do |label| @statusLblBox.pack_start label, false end self.pack_start @cntrlBtnBox, false self.pack_start @statusLblBox self.pack_start @playlistViewWin self.pack_end @statusBar, false self.show_all begin @server.connect( ENV['XMMS_PATH'] ) @server.add_to_glib_mainloop rescue @statusBar.push( @statusBar.get_context_id( "connection" ), "Failed to connect to #{ENV['XMMS_PATH']}" ) end @playBtn.signal_connect :clicked do self.toggle_playback end @stopBtn.signal_connect :clicked do self.stop_playback end @nextBtn.signal_connect :clicked do self.step_in_playlist 1 end @prevBtn.signal_connect :clicked do self.step_in_playlist -1 end @rptBtn.signal_connect :clicked do self.toggle_repeat end @playlistView.signal_connect :row_activated do |view, path, column| @server.playlist_set_next( path.to_str.to_i ).notifier do @server.playback_tickle.notifier do true end true end end @server.broadcast_coll_changed do end @server.broadcast_config_value_changed do |*foo| p foo end @server.broadcast_mediainfo_reader_status do end @server.broadcast_medialib_entry_added do end @server.broadcast_medialib_entry_changed do end @server.broadcast_playback_current_id.notifier do |id| self.handle_current_song id end @server.broadcast_playback_status.notifier do |playing| self.handle_playback_status playing end @server.broadcast_playback_volume_changed do end @server.broadcast_playlist_changed do end @server.broadcast_playlist_current_pos.notifier do |pos| self.handle_current_pos pos end @server.broadcast_playlist_loaded do end @server.broadcast_quit do end self.resync_state end def toggle_playback if @playbackState == 1 @server.playback_pause.notifier do |res| @statusBar.push( @statusBar.get_context_id( "playback" ), "Paused playback" ) true end elsif @playbackState == 0 || 2 @server.playback_start.notifier do |res| @statusBar.push( @statusBar.get_context_id( "playback" ), "Started playback" ) true end else warn "Playbackstate unknown" @server.playback_start.notifier do |res| @statusBar.push( @statusBar.get_context_id( "playback" ), "Started playback" ) true end end end def stop_playback @server.playback_stop.notifier do |res| @statusBar.push( @statusBar.get_context_id( "playback" ), "Stopped playback" ) true end end def step_in_playlist( offset = 1 ) @server.playlist_set_next_rel( offset ).notifier do @server.playback_tickle.notifier do |res| @statusBar.push( @statusBar.get_context_id( "playback" ), "Skipped playback by #{offset} song#{offset.abs >= 1 ? "s" : ''}" ) true end true end end def handle_playback_status( status ) @playbackState = status @stateLbl.text = case status when 0 then "stopped" when 1 then "playing" when 2 then "paused" else "unknown" end true end def handle_current_song( id ) @server.medialib_get_info( id ).notifier do |songinfo| @playbackLbl.text = "" songinfo.each_key do |key| songinfo[key].each_pair do |src,value| # info.each_pair do |src, value| @playbackLbl.text += "[#{src}] #{key} = #{value}\n" end end true end true end def handle_current_pos( pos ) # @server.playlist.entries.notifier do |playlist| # @server.medialib_get_info( playlist[pos[:position]] ).notifier do |songinfo| # @nextSongLbl.text = "" # songinfo.each_pair do |key, info| # info.each_pair do |src, value| # @nextSongLbl.text += "[#{src}] #{key} = #{value}\n" # end # end # true # end # true # end true end def handle_playlist( playlist ) playlist.each_with_index do |id, index| current_row = @playlistList.append @server.medialib_get_info( id ).notifier do |songinfo| current_row[0] = songinfo[:artist] ? songinfo[:artist].first[1] : "NONE" current_row[1] = songinfo[:title] ? songinfo[:title].first[1] : "NONE" true end end @playlistView.model = @playlistList true end def toggle_repeat if @currentconfig[:"playlist.repeat_all"] == "1" if @currentconfig[:"playlist.repeat_one"] == "1" @repeatLbl.text = "none" @server.config_set_value( "playlist.repeat_all", "0" ).notifier do |res| @server.config_get_value( "playlist.repeat_all" ).notifier do |value| @currentconfig[:"playlist.repeat_all"] = value true end true end @server.config_set_value( "playlist.repeat_one", "0" ).notifier do |res| @server.config_get_value( "playlist.repeat_one" ).notifier do |value| @currentconfig[:"playlist.repeat_one"] = value true end true end elsif @currentconfig[:"playlist.repeat_one"] == "0" @repeatLbl.text = "one" @server.config_set_value( "playlist.repeat_one", "1" ).notifier do |res| @server.config_get_value( "playlist.repeat_one" ).notifier do |value| @currentconfig[:"playlist.repeat_one"] = value true end true end else warn "Unknown state" end elsif @currentconfig[:"playlist.repeat_all"] == "0" @repeatLbl.text = "all" @server.config_set_value( "playlist.repeat_one", "0" ).notifier do |res| @server.config_get_value( "playlist.repeat_one" ).notifier do |value| @currentconfig[:"playlist.repeat_one"] = value true end true end @server.config_set_value( "playlist.repeat_all", "1" ).notifier do |res| @server.config_get_value( "playlist.repeat_all" ).notifier do |value| @currentconfig[:"playlist.repeat_all"] = value true end true end else warn "Unknown state" end true end def resync_state @server.config_list_values.notifier do |res| @currentconfig = {} res.each_pair do |key, value| @currentconfig[key] = value end @repeatLbl.text = if( @currentconfig[:"playlist.repeat_one"] == "1" ) "one" elsif @currentconfig[:"playlist.repeat_all"] == "1" "all" else "none" end true end true @server.playlist.entries.notifier do |playlist| self.handle_playlist playlist true end end end class Grux::MainWin < Gtk::Window def initialize super @mainCont = Gtk::VBox.new @btnCont = Gtk::HBox.new @clntCont = Gtk::Notebook.new @cnnctBtn = Gtk::Button.new "_Connect" @quitBtn = Gtk::Button.new "_Quit" self.title = "Grux" @winDstryHndlr = self.signal_connect :destroy do Gtk.main_quit end @cnnctBtnHndlr = @cnnctBtn.signal_connect :clicked do @clntCont.append_page( Grux::ClientWin.new, Gtk::Label.new( "Client" ) ) end @quitBtnHndlr = @quitBtn.signal_connect :clicked do Gtk.main_quit end @btnCont.pack_start @cnnctBtn @btnCont.pack_end @quitBtn @mainCont.pack_start @btnCont, false @mainCont.pack_end @clntCont self.add @mainCont self.show_all end end gruxWin = Grux::MainWin.new Gtk.main