Пример #1
0
    def __init__(self, *args, **kwargs):
        assert 'backend' in kwargs
        self.backend = kwargs.pop('backend')
        MainWindow.__init__(self, *args, **kwargs)

        self.progress_timer = wx.Timer(self, wx.ID_ANY)
        self.state = None
        self.current_song = None

        # Event bindings
        self.Connect(-1, -1, ChangesEvent.CHANGES_EVT_ID, self.refresh)
        self.Connect(-1, -1, BackendConnectedEvent.BACKEND_CONNECTED_EVT_ID, self.connected)
        self.Bind(wx.EVT_TIMER, self.update_progress)
        self.Bind(wx.EVT_MENU, self.do_rescan_database, self.item_rescan)
        self.progress_slider.Bind(wx.EVT_SLIDER, self.do_seek)
        self.volume_slider.Bind(wx.EVT_SLIDER, self.do_volume_set)

        self.initialize_poller = Poller(
            try_func=self.try_to_initialize_backend,
            exception_handler=self.handle_backend_error,
            success_handler=self.handle_backend_success,
        )
Пример #2
0
class DuckWindow(MainWindow):

    updates = set([
        'progress_slider',
        'volume_slider',
    ])

    def try_to_initialize_backend(self):
        self.backend.initialize()

    def handle_backend_error(self, e):
        logger.error('Error starting up backend: %s.' % e)

    def handle_backend_success(self, res):
        logger.debug('Connected!')
        wx.PostEvent(self, BackendConnectedEvent())

    def connected(self, evt):
        self.playlist.refresh()
        self.reload_library()
        self.update_status()
        self.backend.idle()

    def __init__(self, *args, **kwargs):
        assert 'backend' in kwargs
        self.backend = kwargs.pop('backend')
        MainWindow.__init__(self, *args, **kwargs)

        self.progress_timer = wx.Timer(self, wx.ID_ANY)
        self.state = None
        self.current_song = None

        # Event bindings
        self.Connect(-1, -1, ChangesEvent.CHANGES_EVT_ID, self.refresh)
        self.Connect(-1, -1, BackendConnectedEvent.BACKEND_CONNECTED_EVT_ID, self.connected)
        self.Bind(wx.EVT_TIMER, self.update_progress)
        self.Bind(wx.EVT_MENU, self.do_rescan_database, self.item_rescan)
        self.progress_slider.Bind(wx.EVT_SLIDER, self.do_seek)
        self.volume_slider.Bind(wx.EVT_SLIDER, self.do_volume_set)

        self.initialize_poller = Poller(
            try_func=self.try_to_initialize_backend,
            exception_handler=self.handle_backend_error,
            success_handler=self.handle_backend_success,
        )

    def initialize(self):
        self.playlist.set_search_field(self.playlist_search)
        self.artist_list.set_search_field(self.library_search_field)
        self.progress_slider.SetValue(0)
        self.notebook.ChangeSelection(0)
        if _NOTIFY:
            self.notification = pynotify.Notification('duck music player')
        else:
            self.notification = None

        for c in [self.playlist, self.artist_list, self.album_list, self.song_list]:
            c.initialize(self)

        self.initialize_poller.start()

    def handle_changes(self, changes, skip_updates=None):
        if changes:
            logger.debug('changes:\n%s' % changes)
        status_logger.debug('[handle_changes]')
        self.update_status(skip_updates, changes)

    def refresh(self, event):
        with self.backend:
            changes = event.get_changes()
            self.handle_changes(changes)

    @command
    def do_change_song(self, songid):
        """
        Tell the backend to change to song with `songid` in the current
        playlist.
        """
        self.backend.playid(songid)

    @command
    def do_filter_artist(self, selected_artist):
        self.album_list.load(sorted(self.backend.list(
            'album', 'artist', selected_artist)))
        self.song_list.load(sorted(self.backend.list(
            'title', 'artist', selected_artist)))

    @command
    def do_filter_album(self, event):
        selected_album = event.GetItem().GetText()
        self.song_list.load(sorted(self.backend.list(
            'title', 'album', selected_album)))

    @command
    def do_previous(self, event):
        self.backend.previous()

    @command
    def do_play(self, event):
        if self.backend.playlist.songs:
            self.backend.play()
            self.progress_slider.Enable(True)
        else:
            # TODO: Show a dialog with message
            print 'Playlist is empty'

    @command
    def do_pause(self, event):
        self.backend.pause()

    @command
    def do_stop(self, event):
        self.backend.stop()

    @command
    def do_next(self, event):
        logger.debug('do_next')
        self.backend.next()

    @command
    def do_seek(self, event):
        logger.debug(event.GetEventType())
        slider = event.GetEventObject()
        self.backend.seek(slider.GetValue())

    @command
    def do_volume_set(self, event):
        logger.debug('volume set')
        logger.debug(event.GetEventType())
        val = event.GetEventObject().GetValue()
        self.backend.setvol(val)

    @command
    def do_clear(self, event):
        self.backend.clear()
        wx.PostEvent(self, ChangesEvent(['playlist']))

    @command
    def do_add_artist(self, event):
        self.backend.add_artist(event.GetItem().GetText())
        wx.PostEvent(self, ChangesEvent(['playlist']))

    @command
    def do_add_album(self, event):
        self.backend.add_album(event.GetItem().GetText())
        wx.PostEvent(self, ChangesEvent(['playlist']))

    @command
    def do_rescan_database(self, event):
        self.backend.rescan_database()

    def on_play(self):
        self.progress_slider.Enable(True)

    def on_stop(self):
        self.stop_timer()
        self.progress_slider.SetValue(0)
        self.progress_slider.Enable(False)

    def stop_timer(self):
        if self.progress_timer.IsRunning():
            self.progress_timer.Stop()

    def on_pause(self):
        self.stop_timer()
        self.progress_slider.Enable(False)

    def update(self, skip_updates=None):
        status_logger.debug('[update]')
        new_song = self.backend.current_song(sync=True)

        if self.current_song is None or self.current_song.id != new_song.id:
            self.playlist.change_song(self.current_song, new_song)
            self.current_song = new_song
            self.SetTitle('%s - %s' % (new_song.artist, new_song.title))
            self.status_bar.SetStatusText(
                '%s - %s' % (new_song.artist, new_song.title)
            )
            if _NOTIFY:
                self.notification.update(
                    'Now Playing',
                    '%s - %s' % (new_song.artist, new_song.title)
                )
                self.notification.show()

        playlist_changes = self.backend.playlist_changes()
        if playlist_changes:
            self.playlist.refresh()

        if self.backend.status['state'] == 'play':
            self.progress_timer.Start(1000, oneShot=False)
        for u in self.updates - set(skip_updates or []):
            getattr(self, 'update_' + u)()

    def update_progress_slider(self):
        self.progress_slider.SetRange(0, self.backend.time)
        self.progress_slider.SetValue(self.backend.elapsed_time)

    def update_volume_slider(self):
        self.volume_slider.SetValue(self.backend.volume)

    def update_progress(self, event):
        self.progress_slider.SetValue(self.progress_slider.GetValue() + 1)

    def update_status(self, skip_updates=None, changes=None):
        status_logger.debug('[update_status]')
        state = self.backend.get_status()['state']
        getattr(self, 'on_' + state)()
        self.state = state
        if changes and 'playlist' in changes:
            self.playlist.refresh()
        if state != 'stop':
            self.update(skip_updates)

    def reload_library(self):
        for c in [self.album_list, self.song_list]:
            c.DeleteAllItems()
        self.artist_list.refresh()