def __init__(self): self.lyrics = None self.lyricsTimer = None self.player = Player() self.player.registerOnPlayerConnected(self.onPlayerConnected) self.player.registerOnSongChange(self.onSongChanged) self.player.registerOnPlay(self.onPlay) self.player.registerOnStop(self.onStop) self.player.registerOnElapsedChanged(self.onSeek) self.lyricsEngine = LyricsEngine(self.onLyricsFound, self.onEngineFinish) self.lyricsEngine.setLyricsSources(['alsong', 'minilyrics', 'lrcdb', 'lyricsscreenlet']) self.label = gtk.Label("Lyrics Applet") self.gconf_client = gconf.client_get_default() self.gconf_client.add_dir("/apps/lyrics_applet", gconf.CLIENT_PRELOAD_NONE) self.gconf_client.notify_add('/apps/lyrics_applet/color', self.color_changed) self.gconf_client.notify_add('/apps/lyrics_applet/font', self.font_changed) self.color_changed(None) self.font_changed(None)
class LyricsScreenlet(screenlets.Screenlet):#Widget """Shows lyrics of the linux audio players""" # default meta-info for Screenlets __name__ = 'Lyrics Screenlet' __version__ = '0.7.1+' __author__ = 'Marcel Dancak' __desc__ = __doc__ invisible = False maximized = None maxi_width = 300 maxi_height = 155 state = None player = None playing = False songInfo = None lyricsPanel = None autoHideTimer = None autoColorTimer = None lyricsList = None lyrics_index = 0 install_path = None lyrics_directory = os.environ['HOME'] saveFirstLyrics = False # save flag for addlyrics save_lyrics = False dirOption = None filter_cjk = True autoColorAdapt = False autoPanelHide = True colorAdaptation = 'None' textAlign = _('Center') translation_enabled = False language = None # graphics, forwarded to LyricsPanel text_scale = None font = "sans 9" color_normal = None color_highlight = None canvas = None dimensions = None #controlPanel = None minimizeToTray = False trayIcon = None safe_minimize = True # constructor def __init__(self, **keyword_args): #call super (and not show window yet) screenlets.Screenlet.__init__(self, uses_theme=True, width=64, height=64, drag_drop=True, **keyword_args) self.window.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_NORMAL) self.translateMenuItem = gtk.CheckMenuItem("Google Translate") self.translateMenuItem.connect("activate", lambda item: self.__setattr__('translation_enabled', item.get_active())) self.translateMenuItem.show() #print dir(self.window.get_screen()) #print self.window.get_screen().is_composited() #print self.window.get_screen().get_rgba_colormap() self.lyricsPanel = LyricsPanel() #self.lyricsPanel = LyricsAnimation() # path to screenlet installation directory self.install_path = path.dirname(path.abspath(__file__)) + os.sep sys.path.append(self.install_path) # Options self.add_options_group(_('Lyrics'), _('Lyrics settings')) self.add_option(FontOption (_('Lyrics'), 'font', self.font, _('Font'), _('The font of lyrics'))) self.add_option(ColorOption(_('Lyrics'), 'color_normal', self.color_normal, _('Normal Color'), _('Color of the common text'))) self.add_option(ColorOption(_('Lyrics'), 'color_highlight', self.color_highlight, _('Highlight Color'), _('Color of the actual line'))) self.add_option(StringOption(_('Lyrics'), 'colorAdaptation', self.colorAdaptation, _('Color Adaptation'), _('Lyrics text color adaptation by background'), choices = [_('None'), _('Inverse'), _('Black or White')])) self.add_option(FloatOption(_('Lyrics'), 'text_scale', self.text_scale, _('Text Scale'), _('Maximum scale of the highlighted text'), min=1, max=2, increment=0.05, digits=2)) self.add_option(StringOption(_('Lyrics'), 'textAlign', self.textAlign, _('Text Align'), _('Lyrics text align'), choices = sorted(text_aligns))) self.add_option(BoolOption(_('Lyrics'), 'save_lyrics', self.save_lyrics, _('Save lyrics'), _('Allow saving downloaded lyrics to the selected directory'))) self.dirOption = DirectoryOption(_('Lyrics'), 'lyrics_directory', self.lyrics_directory, _('Lyrics Directory'), _('Directory, where will be downloaded lyrics saved')) self.add_option(self.dirOption) self.add_option(BoolOption(_('Lyrics'), 'filter_cjk', self.filter_cjk, _('Filter some languages'), _('Filter Chinese, Japanese, Korean languages (maybe more), which may cause troubles with scaling text during animation '))) self.add_option(BoolOption(_('Lyrics'), 'autoPanelHide', self.autoPanelHide, _('Hiding Control panel'), _('Hide Control panel when window loose focus'))) self.add_option(BoolOption(_('Lyrics'), 'minimizeToTray', self.minimizeToTray, _('Use Tray Icon'), _('Use Tray Icon'))) self.add_option(BoolOption(_('Lyrics'), 'safe_minimize', self.safe_minimize, _('Safe minimizing'), _('Use safe minimizing without real window resizing'))) self.add_options_group(_('Google Translate'), _('Google Translate settings')) self.add_option(BoolOption(_('Google Translate'), 'translation_enabled', self.translation_enabled, _('Enabled'), _('Google Translate'))) self.add_option(StringOption(_('Google Translate'), 'language', self.language, _('Language'), _('Language'), choices = sorted(languages))) self.lyricsEngine = LyricsEngine(self.addLyrics, self.onEngineFinish) self.lyricsEngine.setLyricsSources(['alsong', 'minilyrics', 'lrcdb', 'lyricsscreenlet']) #self.lyricsEngine.setLyricsSources(['lyricsscreenlet']) self.player = player.Player() self.xmmsPlayer = None for p in self.player.player_list: if p.__name__ == "xmms": self.xmmsPlayer = p self.player.registerOnSongChange(self.onSongChanged) self.player.registerOnPlay(self.onPlay) self.player.registerOnStop(self.onStop) self.player.registerOnElapsedChanged(self.onElapsed) self.player.registerOnPlayerConnected(self.onPlayerConnected) self.player.registerOnPlayerDisconnected(self.onPlayerDisconnected) self.player.registerOnActivePlayerListChange(self.onPlayerListChange) self.disconn = ImageButton('disconnected', 'disconnected') self.disconn.registerEvent('button_pressed', self.on_minimized_pressed) self.disconn.registerEvent('button_pressed', self.lyricsPanel_pressed) # moving screenlet self.disconn.registerEvent('resized', self.on_minimized_resized) self.disconn.setPosition(0, 0) self.disconn.setVisible(False) self.disconn.rectangleBounds = True # better for transparent images/themes templateAnim = Animation(100, 6) templateAnim.addLinearTransition('setOverAlpha', 0.0, 1.0, LINEAR) templateAnim.addTransition('scale', LinearVectorInterpolator([1.0, 1.0], [1.4, 1.4]), LINEAR) pressedAnim = Animation(4, 20) pressedAnim.addTransition('scale', LinearVectorInterpolator([1.4, 1.4], [1.25, 1.25]), LINEAR) self.next = ImageButton('next', 'next_over') self.next.registerEvent('button_pressed', self.nextLyrics) self.next.setEnterAnimation(templateAnim.create(self.next)) self.next.setPressedAnimation(pressedAnim.create(self.next)) self.prev = ImageButton('prev', 'prev_over') self.prev.registerEvent('button_pressed', self.previousLyrics) self.prev.setEnterAnimation(templateAnim.create(self.prev)) self.prev.setPressedAnimation(pressedAnim.create(self.prev)) self.save = ImageButton('harddisk', 'harddisk') self.save.registerEvent('button_pressed', self.saveButtonPressed) self.save.setEnterAnimation(templateAnim.create(self.save)) self.save.setEnabled(self.save_lyrics) self.search = ImageButton('search', 'search') self.search.registerEvent('button_pressed', self.onSearchClicked) self.search.setEnterAnimation(templateAnim.create(self.search)) self.upload = ImageButton('upload', 'upload') self.upload.registerEvent('button_pressed', self.uploadButtonPressed) self.upload.setEnterAnimation(templateAnim.create(self.upload)) self.invisibleButton = ImageButton('bubak', 'bubak') self.invisibleButton.visibilityThreshold = 50 # more transparent icon is planned for this self.invisibleButton.registerEvent('button_pressed', self.invisible_pressed) self.notifier = Label(_('Uploaded '), fixedSize = False) self.notifier.bgColor = [0.7, 0.4, 0.4, 0.8] self.notifier.setVisible(False) self.notifier.animation = animation.CompositeAnimation(10, 500) self.notifier.animation.addTransition(self.notifier.__setattr__, animation.LinearScalarInterpolator(1.0, 0.0), 'alpha') self.notifier.animation.addTaskOnFinish(self.notifier.setVisible, False) self.notifier.animation.startupDelay = 2000 self.label = Label('1 of 1', fixedSize = True) prefSize = self.label.getPrefferedSize() self.label.setSize(40, prefSize[1]+6) self.label.align = Label.CENTER # component for resizing screenlet self.resize = ImageButton('resize', 'resize') self.resize.registerEvent('button_pressed', self.onResizeStart) self.resize.registerEvent('mouse_drag_motion', self.onResize) self.resize.registerEvent('button_released', self.do_resize) self.lyricsPanel.setPosition(0, 0) self.lyricsPanel.registerEvent('button_pressed', self.lyricsPanel_pressed) self.searching = ImageButton('searching_bg', 'searching_bg') self.searching_arrow = ImageButton('searching_glow', 'searching_glow') self.searching.addWidget(self.searching_arrow) self.searching.animation = animation.CompositeAnimation(20, 800, loop = True) self.searching.animation.addTransition(self.searching_arrow.__setattr__, animation.LinearScalarInterpolator(0.0, 6.29), 'rotation') self.searching.setVisible(False) #""" from gui.cairo_widgets import CairoCanvas #from gui.ls_widget import VirtualCanvas self.canvas = CairoCanvas(self.window) #self.canvas = VirtualCanvas(self.window) self.canvas.addWidget(self.lyricsPanel) self.canvas.addWidget(self.notifier) self.canvas.addWidget(self.searching) self.canvas.addWidget(self.resize) self.canvas.addWidget(self.disconn) self.canvas.addWidget(self.invisibleButton) self.playersDropDown = DropDownList([_('Not Connected')]) self.playersDropDown.registerItemSelected(self.activePlayerChanged) self.playersDropDown.setSize(100, 20) self.controlPanel = Widget() self.controlPanel.addWidget(self.next) self.controlPanel.addWidget(self.label) self.controlPanel.addWidget(self.prev) self.controlPanel.addWidget(self.search) self.controlPanel.addWidget(self.save) self.controlPanel.addWidget(self.upload) tf = TextField(100, 30, "heloo") #self.canvas.addWidget(tf) self.canvas.addWidget(self.controlPanel) self.canvas.addWidget(self.playersDropDown) # set theme self.theme_name = 'default' self.updateWidgetPositions(self.width, self.height) def translate_callback(self, arg): print arg print arg.get_active() # attribute-"setter", handles setting of attributes def __setattr__(self, name, value): #if name == 'text_scale' or name == 'font' or name == 'color_highlight' or name == 'color_normal': # print name + ': '+str(value) if name == 'colorAdaptation': if value == 'None': if self.autoColorTimer != None: gobject.source_remove(self.autoColorTimer) self.autoColorTimer = None self.colorAnimation(self.color_normal, self.color_highlight) elif self.autoColorTimer == None: self.autoColorTimer = gobject.timeout_add(1000, self.doColorAdaptation) # forward options to LyricsPanel if name in ['color_normal', 'color_highlight', 'text_scale', 'theme', 'textAlign']: if name == 'textAlign': self.lyricsPanel.__setattr__(name, text_aligns[value]) else: self.lyricsPanel.__setattr__(name, value) if name == 'font' and isinstance(value, str): self.lyricsPanel.setFont(pango.FontDescription(value)) if name == 'lyrics_directory': if isinstance(value, bool): return if name == 'save_lyrics': self.save.setEnabled(value) # call Screenlet.__setattr__ in baseclass (ESSENTIAL!!!!) # forward value to canvas if name == 'scale' and self.canvas != None: self.canvas.scale = value screenlets.Screenlet.__setattr__(self, name, value) if name == 'theme_name': #print "THEME CHANGED %s" % value self.onThemeChanged(self.theme) if (name == 'width' or name == 'height') and self.canvas != None: self.updateWidgetPositions(self.width, self.height) if name in [ "playing"]: print "UPDATE STATE %s = %s" % (name, value) #self.updateState() if name == 'minimizeToTray': if value == True: if self.trayIcon == None: self.trayIcon = gtk.StatusIcon() trayIconImage = os.path.dirname(os.path.abspath(__file__)) + os.sep + "tray.png" self.trayIcon.set_from_file(trayIconImage) self.trayIcon.set_tooltip("yep, even screenlets can have tray icon :D") self.trayIcon.connect('activate', self.tray_activate) else: self.trayIcon.set_visible(True) if value == False and self.trayIcon: self.trayIcon.set_visible(False) if name == 'language': if self.lyricsList != None: self.setLyricsIndex(self.lyrics_index) if name == 'translation_enabled': print "\tGOOGLE TRANSLATE: %s" % (self.translation_enabled) self.translateMenuItem.set_active(value) if self.lyricsList != None: self.setLyricsIndex(self.lyrics_index) def on_init (self): log.info(_("Screenlet has been initialized.")) # add default menuitems #self.add_menuitem("translation", "Google Translate") self.menu.append(self.translateMenuItem) self.add_default_menuitems() self.state = self.load_option('state') if self.state == None: self.state = 'minimized' # default state self.session.backend.save_option(self.id, 'state', self.state) log.debug(_("MINIMIZING Startup state: %s") % self.state) width = self.load_option('maxi_width' ) height = self.load_option('maxi_height') if (width != None and height != None): self.maxi_width = int(width ) self.maxi_height = int(height) log.debug("MINIMIZING Initialized maximized dimensions: width=%d height=%d" % (self.maxi_width, self.maxi_height)) self.minimize("disconnected") def tray_activate(self, widget): if self.state == 'minimized': self.maximize() else: self.minimize() def on_menuitem_select(self, item): print item def on_minimized_resized(self, width, height): print "on_minimized_resized: w=%d h=%d" % (width, height) if self.state == 'minimized' and not self.safe_minimize: self.width = width self.height = height #self.canvas.setSize(width, height) #self.update_shape() def on_minimized_pressed(self, widget, event): if event.type == gtk.gdk._2BUTTON_PRESS: self.maximize() def pack(self, widget): screen = self.window.get_screen() log.debug(_("MINIMIZING Compute minimized layout")) log.debug("MINIMIZING Screen: width=%d height=%d" % (screen.get_width(), screen.get_height())) log.debug("MINIMIZING Maximized dimmensions: width=%d height=%d" % (self.maxi_width, self.maxi_height)) #print "x=%s y=%s width=%s" % (self.x, self.y, self.maxi_width) left = self.x right = screen.get_width() - (left + self.maxi_width) up = self.y bottom = screen.get_height() - (up + self.maxi_height) #print "PACK LEFT=%s RIGHT=%s" % (left, right) ml = (left/float(left+right))*(self.maxi_width-widget.bounds.width) #mr = (1.0-(left/float(left+right)))*(self.maxi_width-widget.bounds.width) #print "%s vs %s" % (ml, mr) mu = (up/float(up+bottom))*(self.maxi_height-widget.bounds.height) #print "offset x=%s y=%s" % (ml, mu) return [ml, mu] def expand(self, widget, width, height): screen = self.window.get_screen() screenWidth = screen.get_width() screenHeight = screen.get_height() #print "prev x=%s widget.bounds.x=%s" % (self.x, widget.bounds.x) prevX = self.x + widget.bounds.x prevY = self.y + widget.bounds.y left = prevX right = screenWidth - (prevX+widget.bounds.width) up = prevY bottom = screenHeight - (prevY+widget.bounds.height) #print "LEFT=%s RIGHT=%s" % (left, right) #print "right/left %s" % (right/float(left+right)) #print "MOVE LEFT %s" % ((1.0-right/float(left+right))*(width-widget.bounds.width)) #print "MOVE RIGHT %s" % (right/float(left+right)*(width-widget.bounds.width)) #left*ratio + right*ratio = width ratioH = width/float(left+right) ratioV = height/float(up+bottom) #left*r + right*r = widget.bounds.width rh = widget.bounds.width/float(left+right) rv = widget.bounds.height/float(up+bottom) newX = int(prevX+rh*left-ratioH*left) newY = int(prevY+rv*up-ratioV*up) new = [int(prevX-(1.0-right/float(left+right))*(width-widget.bounds.width))] #print "%s vs %s" % (new, newX) return [newX, newY] def load_option(self, name): if self.session != None: try: return self.session.backend.load_option(self.id, name) except Exception, e: pass
def __init__(self, **keyword_args): #call super (and not show window yet) screenlets.Screenlet.__init__(self, uses_theme=True, width=64, height=64, drag_drop=True, **keyword_args) self.window.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_NORMAL) self.translateMenuItem = gtk.CheckMenuItem("Google Translate") self.translateMenuItem.connect("activate", lambda item: self.__setattr__('translation_enabled', item.get_active())) self.translateMenuItem.show() #print dir(self.window.get_screen()) #print self.window.get_screen().is_composited() #print self.window.get_screen().get_rgba_colormap() self.lyricsPanel = LyricsPanel() #self.lyricsPanel = LyricsAnimation() # path to screenlet installation directory self.install_path = path.dirname(path.abspath(__file__)) + os.sep sys.path.append(self.install_path) # Options self.add_options_group(_('Lyrics'), _('Lyrics settings')) self.add_option(FontOption (_('Lyrics'), 'font', self.font, _('Font'), _('The font of lyrics'))) self.add_option(ColorOption(_('Lyrics'), 'color_normal', self.color_normal, _('Normal Color'), _('Color of the common text'))) self.add_option(ColorOption(_('Lyrics'), 'color_highlight', self.color_highlight, _('Highlight Color'), _('Color of the actual line'))) self.add_option(StringOption(_('Lyrics'), 'colorAdaptation', self.colorAdaptation, _('Color Adaptation'), _('Lyrics text color adaptation by background'), choices = [_('None'), _('Inverse'), _('Black or White')])) self.add_option(FloatOption(_('Lyrics'), 'text_scale', self.text_scale, _('Text Scale'), _('Maximum scale of the highlighted text'), min=1, max=2, increment=0.05, digits=2)) self.add_option(StringOption(_('Lyrics'), 'textAlign', self.textAlign, _('Text Align'), _('Lyrics text align'), choices = sorted(text_aligns))) self.add_option(BoolOption(_('Lyrics'), 'save_lyrics', self.save_lyrics, _('Save lyrics'), _('Allow saving downloaded lyrics to the selected directory'))) self.dirOption = DirectoryOption(_('Lyrics'), 'lyrics_directory', self.lyrics_directory, _('Lyrics Directory'), _('Directory, where will be downloaded lyrics saved')) self.add_option(self.dirOption) self.add_option(BoolOption(_('Lyrics'), 'filter_cjk', self.filter_cjk, _('Filter some languages'), _('Filter Chinese, Japanese, Korean languages (maybe more), which may cause troubles with scaling text during animation '))) self.add_option(BoolOption(_('Lyrics'), 'autoPanelHide', self.autoPanelHide, _('Hiding Control panel'), _('Hide Control panel when window loose focus'))) self.add_option(BoolOption(_('Lyrics'), 'minimizeToTray', self.minimizeToTray, _('Use Tray Icon'), _('Use Tray Icon'))) self.add_option(BoolOption(_('Lyrics'), 'safe_minimize', self.safe_minimize, _('Safe minimizing'), _('Use safe minimizing without real window resizing'))) self.add_options_group(_('Google Translate'), _('Google Translate settings')) self.add_option(BoolOption(_('Google Translate'), 'translation_enabled', self.translation_enabled, _('Enabled'), _('Google Translate'))) self.add_option(StringOption(_('Google Translate'), 'language', self.language, _('Language'), _('Language'), choices = sorted(languages))) self.lyricsEngine = LyricsEngine(self.addLyrics, self.onEngineFinish) self.lyricsEngine.setLyricsSources(['alsong', 'minilyrics', 'lrcdb', 'lyricsscreenlet']) #self.lyricsEngine.setLyricsSources(['lyricsscreenlet']) self.player = player.Player() self.xmmsPlayer = None for p in self.player.player_list: if p.__name__ == "xmms": self.xmmsPlayer = p self.player.registerOnSongChange(self.onSongChanged) self.player.registerOnPlay(self.onPlay) self.player.registerOnStop(self.onStop) self.player.registerOnElapsedChanged(self.onElapsed) self.player.registerOnPlayerConnected(self.onPlayerConnected) self.player.registerOnPlayerDisconnected(self.onPlayerDisconnected) self.player.registerOnActivePlayerListChange(self.onPlayerListChange) self.disconn = ImageButton('disconnected', 'disconnected') self.disconn.registerEvent('button_pressed', self.on_minimized_pressed) self.disconn.registerEvent('button_pressed', self.lyricsPanel_pressed) # moving screenlet self.disconn.registerEvent('resized', self.on_minimized_resized) self.disconn.setPosition(0, 0) self.disconn.setVisible(False) self.disconn.rectangleBounds = True # better for transparent images/themes templateAnim = Animation(100, 6) templateAnim.addLinearTransition('setOverAlpha', 0.0, 1.0, LINEAR) templateAnim.addTransition('scale', LinearVectorInterpolator([1.0, 1.0], [1.4, 1.4]), LINEAR) pressedAnim = Animation(4, 20) pressedAnim.addTransition('scale', LinearVectorInterpolator([1.4, 1.4], [1.25, 1.25]), LINEAR) self.next = ImageButton('next', 'next_over') self.next.registerEvent('button_pressed', self.nextLyrics) self.next.setEnterAnimation(templateAnim.create(self.next)) self.next.setPressedAnimation(pressedAnim.create(self.next)) self.prev = ImageButton('prev', 'prev_over') self.prev.registerEvent('button_pressed', self.previousLyrics) self.prev.setEnterAnimation(templateAnim.create(self.prev)) self.prev.setPressedAnimation(pressedAnim.create(self.prev)) self.save = ImageButton('harddisk', 'harddisk') self.save.registerEvent('button_pressed', self.saveButtonPressed) self.save.setEnterAnimation(templateAnim.create(self.save)) self.save.setEnabled(self.save_lyrics) self.search = ImageButton('search', 'search') self.search.registerEvent('button_pressed', self.onSearchClicked) self.search.setEnterAnimation(templateAnim.create(self.search)) self.upload = ImageButton('upload', 'upload') self.upload.registerEvent('button_pressed', self.uploadButtonPressed) self.upload.setEnterAnimation(templateAnim.create(self.upload)) self.invisibleButton = ImageButton('bubak', 'bubak') self.invisibleButton.visibilityThreshold = 50 # more transparent icon is planned for this self.invisibleButton.registerEvent('button_pressed', self.invisible_pressed) self.notifier = Label(_('Uploaded '), fixedSize = False) self.notifier.bgColor = [0.7, 0.4, 0.4, 0.8] self.notifier.setVisible(False) self.notifier.animation = animation.CompositeAnimation(10, 500) self.notifier.animation.addTransition(self.notifier.__setattr__, animation.LinearScalarInterpolator(1.0, 0.0), 'alpha') self.notifier.animation.addTaskOnFinish(self.notifier.setVisible, False) self.notifier.animation.startupDelay = 2000 self.label = Label('1 of 1', fixedSize = True) prefSize = self.label.getPrefferedSize() self.label.setSize(40, prefSize[1]+6) self.label.align = Label.CENTER # component for resizing screenlet self.resize = ImageButton('resize', 'resize') self.resize.registerEvent('button_pressed', self.onResizeStart) self.resize.registerEvent('mouse_drag_motion', self.onResize) self.resize.registerEvent('button_released', self.do_resize) self.lyricsPanel.setPosition(0, 0) self.lyricsPanel.registerEvent('button_pressed', self.lyricsPanel_pressed) self.searching = ImageButton('searching_bg', 'searching_bg') self.searching_arrow = ImageButton('searching_glow', 'searching_glow') self.searching.addWidget(self.searching_arrow) self.searching.animation = animation.CompositeAnimation(20, 800, loop = True) self.searching.animation.addTransition(self.searching_arrow.__setattr__, animation.LinearScalarInterpolator(0.0, 6.29), 'rotation') self.searching.setVisible(False) #""" from gui.cairo_widgets import CairoCanvas #from gui.ls_widget import VirtualCanvas self.canvas = CairoCanvas(self.window) #self.canvas = VirtualCanvas(self.window) self.canvas.addWidget(self.lyricsPanel) self.canvas.addWidget(self.notifier) self.canvas.addWidget(self.searching) self.canvas.addWidget(self.resize) self.canvas.addWidget(self.disconn) self.canvas.addWidget(self.invisibleButton) self.playersDropDown = DropDownList([_('Not Connected')]) self.playersDropDown.registerItemSelected(self.activePlayerChanged) self.playersDropDown.setSize(100, 20) self.controlPanel = Widget() self.controlPanel.addWidget(self.next) self.controlPanel.addWidget(self.label) self.controlPanel.addWidget(self.prev) self.controlPanel.addWidget(self.search) self.controlPanel.addWidget(self.save) self.controlPanel.addWidget(self.upload) tf = TextField(100, 30, "heloo") #self.canvas.addWidget(tf) self.canvas.addWidget(self.controlPanel) self.canvas.addWidget(self.playersDropDown) # set theme self.theme_name = 'default' self.updateWidgetPositions(self.width, self.height)
class Lyrics(object): color = gtk.gdk.Color() font = "Sans 10" applet = None label = None lyrics_directory = "/home/dencer/Lyrics" def __init__(self): self.lyrics = None self.lyricsTimer = None self.player = Player() self.player.registerOnPlayerConnected(self.onPlayerConnected) self.player.registerOnSongChange(self.onSongChanged) self.player.registerOnPlay(self.onPlay) self.player.registerOnStop(self.onStop) self.player.registerOnElapsedChanged(self.onSeek) self.lyricsEngine = LyricsEngine(self.onLyricsFound, self.onEngineFinish) self.lyricsEngine.setLyricsSources(['alsong', 'minilyrics', 'lrcdb', 'lyricsscreenlet']) self.label = gtk.Label("Lyrics Applet") self.gconf_client = gconf.client_get_default() self.gconf_client.add_dir("/apps/lyrics_applet", gconf.CLIENT_PRELOAD_NONE) self.gconf_client.notify_add('/apps/lyrics_applet/color', self.color_changed) self.gconf_client.notify_add('/apps/lyrics_applet/font', self.font_changed) self.color_changed(None) self.font_changed(None) def color_changed(self, client, *args): color = self.gconf_client.get_string("/apps/lyrics_applet/color") if color: self.color = gtk.gdk.Color(color) self.label.modify_fg(gtk.STATE_NORMAL, self.color) def font_changed(self, client, *args): font = self.gconf_client.get_string("/apps/lyrics_applet/font") if font: self.font = font font_desc = pango.FontDescription(font) self.label.modify_font(font_desc) def onPlayerConnected(self): print "onPlayerConnected" def onStop(self): if self.lyricsTimer: self.lyricsTimer.pause() def onPlay(self): if self.lyricsTimer: self.lyricsTimer.resume() def onSeek(self, elapsed): print "## seek to:", elapsed if self.lyrics: self.lyricsTimer.pause() self.lyricsTimer = LyricsTimer(self.lyrics, self.update) self.lyricsTimer.start(elapsed) self.label.set_text(self.lyrics[self.lyricsTimer.actualLine].text[0].strip()) def onSongChanged(self, songFile): try: self.lyrics = None if self.lyricsTimer: self.lyricsTimer.pause() self.lyricsTimer = None print "onSongChanged" metadata = getSongMetadata(self.player) metadata['file'] = songFile self.label.set_text("") print metadata lyrics = self.getLyricsFromDisk(metadata) if lyrics is None: self.lyricsEngine.search(metadata) print "searching started" else: self.onLyricsFound(lyrics) except: traceback.print_exc() def onLyricsFound(self, lyrics): if not self.lyrics and lyrics: print "onLyricsFound" try: parsed = lyricsparser.parseLyrics(lyrics) if isinstance(parsed[0], LyricEntity): self.lyrics = parsed self.lyricsTimer = LyricsTimer(self.lyrics ,self.update) elapsed = self.player.getElapsed() #print "elapsed:", elapsed self.lyricsTimer.start(elapsed) self.label.set_text(self.lyrics[self.lyricsTimer.actualLine].text[0].strip()) self.lyricsEngine.stop() except: traceback.print_exc() def update(self, lyricsLine): lyricLine = self.lyrics[lyricsLine].text[0].strip() if lyricLine: self.label.set_text(self.lyrics[lyricsLine].text[0].strip()) def onEngineFinish(self): print "onEngineFinish" def getLyricsFromDisk(self, songInfo): logger.debug("searching lyrics on disk") # check for .lrc file in song file directory lrc_file = None if songInfo.has_key('file'): lrc_file = songInfo['file'].rstrip("mp3")+"lrc" #TODO: not only mp3 expecting if lrc_file == None or not os.path.exists(lrc_file): lrc_path = lyricsFile(songInfo) lrc_file = os.path.join(self.lyrics_directory, lrc_path['folder'], lrc_path['file']) logger.debug("lyrics should be here: %s" % lrc_file) print lrc_file if lrc_file != None and os.path.exists(lrc_file): f = open(lrc_file, 'r') print "lyrics from file: %s" % lrc_file lrc = f.read() f.close() return lrc print "Nothing on disk" return None def show_about(self, *args): print args pass def show_preferences(self, *args): dialog = OptionsDialog(self) response = dialog.run() if response == gtk.RESPONSE_OK: dialog.save_preferences() dialog.destroy()