Beispiel #1
0
    def set_books(self, page_index, books):
        """ Set books  
        
        :param page_index: page index
        :param books: books
        
        :return: books page
        """
        self.total_pages = books[TOTAL_PAGES]

        left = str(self.current_page - 1)
        right = str(self.total_pages - self.current_page)
        if self.total_pages == 0:
            right = "0"
        if int(right) < 0:
            right = left
        self.navigator.left_button.change_label(left)
        self.navigator.right_button.change_label(right)
        self.set_title(self.current_page)

        folder_content = self.get_books_objects(books[BOOK_SUMMARIES],
                                                self.rows, self.columns,
                                                self.menu_layout)
        return Page(folder_content, self.rows, self.columns)
    def turn_page(self, state=None):
        """ Turn screen page
        
        :param state: button state
        """
        filelist = Page(self.episodes, MENU_ROWS_EPISODES, MENU_COLUMNS_EPISODES)
        
        if state == None:
            pass
            filelist.current_page_index = self.current_page - 1
            index = -1
        else:            
            if getattr(state, "status", None) == STATUS_LOADED:
                if hasattr(state, "original_url") and len(state.original_url.strip()) > 0:
                    filelist.set_current_item_by_url(state.original_url)
                else:
                    filelist.set_current_item_by_file_name(state.file_name)
            else:
                filelist.set_current_item_by_url(state.url)
            
            index = filelist.current_item_index            

        self.current_item = self.config[PODCASTS][PODCAST_EPISODE_NAME]        
        self.current_page = filelist.current_page_index + 1
        
        page = filelist.get_current_page()
        d = self.episodes_menu.make_dict(page)
        self.episodes_menu.set_items(d, filelist.current_page_index, self.select_episode, False)
        self.set_title(self.current_page)
        self.episodes_menu.unselect()
        self.episodes_menu.select_by_index(index)
        
        for b in self.episodes_menu.buttons.values():
            b.parent_screen = self

        self.navigator.get_button_by_name(KEY_PAGE_DOWN).change_label(str(filelist.get_left_items_number()))
        self.navigator.get_button_by_name(KEY_PAGE_UP).change_label(str(filelist.get_right_items_number()))
        self.episodes_menu.clean_draw_update()
        
        if hasattr(self, "update_observer"):
            self.episodes_menu.add_menu_observers(self.update_observer, self.redraw_observer)

        self.link_borders()

        menu_selected = self.menu.get_selected_index()
        if menu_selected == None:
            if self.current_item == None or len(self.current_item) == 0:
                self.menu.select_by_index(0)
                item = self.menu.get_selected_item()
                if item != None:
                    self.current_item = item.state.name

        for b in self.menu.buttons.values():
            b.parent_screen = self
            if self.current_item == b.state.name:
                self.menu.select_by_index(b.state.index)
                self.navigator.unselect()
                return
Beispiel #3
0
class FileMenu(Menu):
    """ File Menu class. Extends base Menu class """
    def __init__(self,
                 filelist,
                 util,
                 playlist_provider,
                 bgr=None,
                 bounding_box=None,
                 align=ALIGN_CENTER):
        """ Initializer
        
        :param filelist: file list
        :param util: utility object
        :param bgr: menu background
        :param bounding_box: bounding box
        """
        self.factory = Factory(util)
        self.util = util
        self.cdutil = CdUtil(self.util)
        self.playlist_provider = playlist_provider
        self.config = self.util.config
        self.filelist = filelist
        m = self.factory.create_file_menu_button
        self.bounding_box = bounding_box

        r = c = 3
        if filelist:
            r = filelist.rows
            c = filelist.columns
        Menu.__init__(self,
                      util,
                      bgr,
                      self.bounding_box,
                      r,
                      c,
                      create_item_method=m,
                      align=align,
                      button_padding_x=5)

        self.browsing_history = {}
        self.left_number_listeners = []
        self.right_number_listeners = []
        self.change_folder_listeners = []
        self.play_file_listeners = []
        self.playlist_size_listeners = []
        self.menu_navigation_listeners = []
        self.page_turned = False
        self.separator = os.sep
        self.empty_state = State()
        url = selection = None
        self.current_folder = self.config[FILE_PLAYBACK][CURRENT_FOLDER]
        folder = self.current_folder

        playback_mode = self.config[FILE_PLAYBACK][CURRENT_FILE_PLAYBACK_MODE]
        if playback_mode == FILE_AUDIO or playback_mode == FILE_RECURSIVE:
            if not self.current_folder.endswith(os.sep):
                self.current_folder += os.sep

            if self.config[CURRENT][MODE] == CD_PLAYER:
                cd_drive_name = self.config[CD_PLAYBACK][CD_DRIVE_NAME]
                track = self.config[CD_PLAYBACK][CD_TRACK]
                url = self.cdutil.get_cd_track_url(cd_drive_name, track)
            else:
                url = self.current_folder + self.config[FILE_PLAYBACK][
                    CURRENT_FILE]
        elif playback_mode == FILE_PLAYLIST:
            url = self.config[FILE_PLAYBACK][CURRENT_FILE]
            self.browsing_history[self.current_folder] = 0
            p = self.current_folder + self.separator + self.config[
                FILE_PLAYBACK][CURRENT_FILE_PLAYLIST]
            self.browsing_history[p] = 0
            folder = p
            self.current_folder = folder
        selection = url

        if url and self.filelist:
            self.filelist.set_current_item_by_url(url)

        p_index = self.filelist.current_page_index
        pl = self.filelist.items
        self.change_folder(folder,
                           page_index=p_index,
                           playlist=pl,
                           selected=selection)

        if not self.config[FILE_PLAYBACK][CURRENT_FOLDER] and not self.config[
                FILE_PLAYBACK][CURRENT_FILE]:
            self.select_first_item()

    def recursive_change_folder(self, state):
        """ Change recursive folder
        
        :param state: state object
        """
        f = self.util.file_util.get_first_folder_with_audio_files(state.url)
        if f == None:
            self.change_folder(state.url)
            self.select_item_on_page(0)
            return

        self.config[FILE_PLAYBACK][CURRENT_FILE_PLAYBACK_MODE] = FILE_RECURSIVE

        self.config[FILE_PLAYBACK][CURRENT_FOLDER] = f[0]
        state.folder = f[0]
        state.file_name = f[1]
        state.file_type = FILE_AUDIO
        state.url = f[1]
        self.change_folder(f[0])
        self.handle_file(state)

    def select_item(self, state):
        """ Select menu item
        
        :param state: state object defining selected object
        """
        if self.visible and (state.file_type == FILE_AUDIO
                             or state.file_type == FILE_PLAYLIST):
            self.config[FILE_PLAYBACK][
                CURRENT_FOLDER] = self.util.file_util.current_folder

        if state.file_type == FOLDER or state.file_type == FOLDER_WITH_ICON:
            if getattr(state, "long_press", False):
                if self.config[FILE_PLAYBACK][
                        CURRENT_FILE_PLAYBACK_MODE] == FILE_RECURSIVE:
                    self.config[FILE_PLAYBACK][
                        CURRENT_FILE_PLAYBACK_MODE] = FILE_AUDIO
                    self.change_folder(state.url)
                    self.select_item_on_page(0)
                else:
                    self.config[FILE_PLAYBACK][
                        CURRENT_FILE_PLAYLIST] = state.url
                    self.recursive_change_folder(state)
            else:
                self.config[FILE_PLAYBACK][
                    CURRENT_FILE_PLAYBACK_MODE] = FILE_AUDIO
                self.change_folder(state.url)
                self.select_item_on_page(0)
        elif state.file_type == FILE_AUDIO:
            if getattr(state, "long_press",
                       False) and self.config[FILE_PLAYBACK][
                           CURRENT_FILE_PLAYBACK_MODE] == FILE_RECURSIVE:
                self.config[FILE_PLAYBACK][
                    CURRENT_FILE_PLAYBACK_MODE] = FILE_AUDIO

            m = getattr(state, "playback_mode", FILE_AUDIO)
            mode = self.config[FILE_PLAYBACK][
                CURRENT_FILE_PLAYBACK_MODE] or FILE_AUDIO
            if m == FILE_AUDIO and mode == FILE_AUDIO:
                self.handle_file(state)
            else:
                self.config[FILE_PLAYBACK][CURRENT_FILE] = state.file_name
                self.config[FILE_PLAYBACK][CURRENT_TRACK_TIME] = None
                if not getattr(state, "dont_notify", None):
                    self.notify_play_file_listeners(state)
                else:
                    n = self.config[AUDIO][CLIENT_NAME]
                    if n == MPLAYER or n == VLC:
                        self.handle_file(state)
        elif state.file_type == FILE_PLAYLIST:
            self.config[FILE_PLAYBACK][
                CURRENT_FILE_PLAYBACK_MODE] = FILE_PLAYLIST
            i = state.url.rfind(self.separator)
            url = state.url[i + 1:]
            self.config[FILE_PLAYBACK][CURRENT_FILE_PLAYLIST] = url
            state.music_folder = self.config[AUDIO][MUSIC_FOLDER]
            pl = self.util.load_playlist(state, self.playlist_provider,
                                         self.filelist.rows,
                                         self.filelist.columns)
            url = state.url
            if pl:
                self.notify_playlist_size_listener(len(pl))
            else:
                url = state.url[0:i]
            u = getattr(state, "url", None)
            if u == None:
                state.url = state.folder + os.sep + state.file_name
                url = state.url

            self.change_folder(url, playlist=pl)

        if self.visible:
            self.draw()

    def handle_event(self, event):
        """ File menu event handler
        
        :param event: event to handle
        """
        if not self.visible: return

        if event.type == USER_EVENT_TYPE and event.sub_type == SUB_TYPE_KEYBOARD and event.action == pygame.KEYUP:
            if event.keyboard_key == kbd_keys[KEY_LEFT]:
                if (self.filelist.current_item_index_in_page == 0
                        and self.filelist.current_item_index != 0
                    ) or self.filelist.current_item_index == 0:
                    if self.filelist.length <= self.filelist.items_per_page:
                        self.select_item_on_page(self.filelist.length - 1)
                    else:
                        self.turn_page_left()
                else:
                    self.select_item_on_page(self.filelist.current_item_index -
                                             1)
            elif event.keyboard_key == kbd_keys[KEY_RIGHT]:
                if self.filelist.current_item_index == self.filelist.length - 1 or self.filelist.current_item_index_in_page == self.filelist.items_per_page - 1:
                    if self.filelist.length <= self.filelist.items_per_page:
                        self.select_item_on_page(0)
                    else:
                        self.turn_page_right()
                else:
                    self.select_item_on_page(self.filelist.current_item_index +
                                             1)
            elif event.keyboard_key == kbd_keys[
                    KEY_UP] or event.keyboard_key == kbd_keys[KEY_DOWN]:
                Menu.handle_event(self, event)
                self.filelist.set_current_item(self.selected_index)
                self.notify_menu_navigation_listeners(self.empty_state)
            elif event.keyboard_key == kbd_keys[KEY_SELECT]:
                Menu.handle_event(self, event)
        else:
            Menu.handle_event(self, event)

    def page_up(self, state=None):
        """ Called by page up button
        
        :param state: not used
        """
        if self.filelist.length <= self.filelist.items_per_page:
            return

        self.switch_to_next_page(None)
        self.select_item_on_page(self.filelist.current_page_index *
                                 self.filelist.items_per_page)

    def page_down(self, state=None):
        """ Called by page down button
        
        :param state: not used
        """
        if self.filelist.length <= self.filelist.items_per_page:
            return

        self.switch_to_previous_page(None)
        self.select_item_on_page(self.filelist.current_page_index *
                                 self.filelist.items_per_page)

    def turn_page_left(self, state=None):
        """ Turn page left
        
        :param state: not used
        """
        if self.filelist.length <= self.filelist.items_per_page:
            return

        self.switch_to_previous_page(None)
        if self.filelist.current_item_index == 0:
            self.select_item_on_page(self.filelist.length - 1)
        elif self.filelist.current_item_index_in_page == 0 and self.filelist.current_item_index != 0:
            self.select_item_on_page(self.filelist.current_item_index - 1)
        else:
            self.select_item_on_page(self.filelist.current_page_index *
                                     self.filelist.items_per_page)

    def turn_page_right(self, state=None):
        """ Turn page right
        
        :param state: not used
        """
        if self.filelist.length <= self.filelist.items_per_page:
            return

        self.switch_to_next_page(None)
        if self.filelist.current_item_index == self.filelist.length - 1:
            self.select_item_on_page(0)
        elif self.filelist.current_item_index_in_page == self.filelist.items_per_page - 1:
            self.select_item_on_page(self.filelist.current_item_index + 1)
        else:
            self.select_item_on_page(self.filelist.current_page_index *
                                     self.filelist.items_per_page)

    def select_item_on_page(self, selected_index):
        """ Select item on page
        
        :param selected_index: index of the selected item
        """
        if self.filelist.length == 0: return
        self.filelist.set_current_item(selected_index)
        self.unselect()
        self.select_by_index(selected_index)
        self.notify_menu_navigation_listeners(self.empty_state)

    def handle_file(self, state):
        """ Handle audio file
        
        :param state: state object defining audio file
        """

        state.track_time = '0'

        if not state.file_name.startswith("cdda:"):
            self.config[FILE_PLAYBACK][CURRENT_FILE] = state.file_name
            self.config[FILE_PLAYBACK][CURRENT_TRACK_TIME] = state.track_time

        if self.is_in_filelist(state.file_name):
            b = self.get_button_by_filename(state.file_name)
            if not b:
                self.switch_to_next_page(state)
            else:
                state.comparator_item = b.state.comparator_item

        if not self.config[FILE_PLAYBACK][CURRENT_FILE].startswith("cdda:"):
            url = self.config[FILE_PLAYBACK][
                CURRENT_FOLDER] + os.sep + self.config[FILE_PLAYBACK][
                    CURRENT_FILE]
            self.filelist.set_current_item_by_url(url)

        mode = getattr(state, "playback_mode", None)
        if mode == None:
            if state.file_type == FILE_AUDIO:
                state.playback_mode = FILE_AUDIO
            else:
                state.playback_mode = FILE_PLAYLIST

        self.item_selected(state)
        if not getattr(state, "dont_notify", None):
            self.notify_play_file_listeners(state)

    def update_playlist_menu(self, state):
        """ Update playlist menu
        This is initiated by player
        
        :param state: state object from player defining current playlist file
        """
        if self.config[FILE_PLAYBACK][
                CURRENT_FILE_PLAYBACK_MODE] != FILE_PLAYLIST:
            return

        s = State()
        s.dont_notify = True

        i = self.util.get_dictionary_value(state, "current_track_id")
        s.track_time = self.util.get_dictionary_value(state, "seek_time", "0")
        self.config[FILE_PLAYBACK][CURRENT_TRACK_TIME] = s.track_time

        if i != None:
            b = self.get_button_by_index_in_page(int(i) - 1)
            if not b:
                self.switch_to_next_page(s)
            s.comparator_item = int(i)

        name = self.util.get_dictionary_value(state, "Track")

        if not name:
            name = self.util.get_dictionary_value(state, "file_name")

        if name != None:
            self.config[FILE_PLAYBACK][CURRENT_FILE] = name

        self.item_selected(state)

    def get_comparator(self, state):
        """ Return comparator object from state
        
        :param state: state object containing comparator item
        """
        try:
            p = state["Pos"]
            return int(p)
        except:
            pass

        try:
            s_comp = getattr(state, "comparator_item", None)
            if s_comp != None:
                return s_comp
        except:
            pass

        s_name = None

        if isinstance(state, dict):
            try:
                s_name = state["file_name"]
            except:
                pass
        elif isinstance(state, State):
            s_name = getattr(state, "file_name", None)

        for button in self.buttons.values():
            b_name = getattr(button.state, "file_name", None)
            if s_name and b_name and s_name == button.state.file_name:
                return button.state.comparator_item
        return None

    def set_current_folder(self, folder):
        """ Current folder setter
        
        :param folder: new current folder
        """
        self.current_folder = folder

    def set_filelist(self, filelist):
        """ Set filelist
        
        :param filelist: the filelist to set
        """
        self.filelist = filelist

    def init_page(self, index):
        """ Page initializer
        
        :param index: new current page index
        """
        url = self.config[FILE_PLAYBACK][CURRENT_FILE]
        if self.config[FILE_PLAYBACK][
                CURRENT_FILE_PLAYBACK_MODE] == FILE_AUDIO:
            url = self.config[FILE_PLAYBACK][
                CURRENT_FOLDER] + os.sep + self.config[FILE_PLAYBACK][
                    CURRENT_FILE]

        if url:
            self.filelist.set_current_item_by_url(url)

        self.filelist.current_page_index = index
        page = self.filelist.get_current_page()
        self.set_page(self.filelist.current_item_index_in_page, page)

        if not self.filelist.current_item:
            self.select_first_item()
        else:
            self.item_selected(self.filelist.current_item)

    def set_page(self, index_on_page, page, align=ALIGN_CENTER):
        """ Page setter
        
        :param index_on_page: current item index on page
        :param page: current page content
        """
        if page == None: return

        self.set_items(self.make_dict(page), index_on_page, self.select_item)
        self.draw()

    def switch_to_next_page(self, state):
        """ Switch to the next page
        
        :param state: button state
        """
        if len(self.filelist.items) == 0:
            return
        self.turn_page(state, self.filelist.next_page())

    def switch_to_previous_page(self, state):
        """ Switch to the previous page
        
        :param state: button state
        """
        if len(self.filelist.items) == 0:
            return
        self.turn_page(state, self.filelist.previous_page())

    def turn_page(self, state, page):
        """ Change current page
        
        :param state: state object defining current item on page
        :param page: new page content
        """
        self.set_page(self.filelist.current_item_index, page)
        if getattr(state, "url", None):
            self.filelist.set_current_item_by_url(state.url)
        if self.visible:
            self.item_selected(self.filelist.current_item)
        self.update_buttons()
        if not getattr(state, "dont_notify", None):
            self.draw()
        self.page_turned = True

        f = self.current_folder

        if f[-1] == self.separator:
            f = f[:-1]

        self.browsing_history[f] = self.filelist.current_page_index

    def switch_to_root(self, state):
        """ Switch to the root folder
        
        :param state: not used state object
        """
        self.switch_folder(self.util.file_util.ROOT)

    def switch_to_user_home(self, state):
        """ Switch to the user home folder
        
        :param state: not used state object
        """
        self.switch_folder(self.util.file_util.USER_HOME)

    def switch_folder(self, folder):
        """ Switch to folder
        
        :param folder: folder to switch to
        """
        self.switch_file_playback_mode()
        self.change_folder(folder)
        self.select_first_item()

    def switch_file_playback_mode(self):
        if self.config[FILE_PLAYBACK][
                CURRENT_FILE_PLAYBACK_MODE] == FILE_PLAYLIST:
            self.config[FILE_PLAYBACK][CURRENT_FILE_PLAYBACK_MODE] = FILE_AUDIO

    def switch_to_parent_folder(self, state):
        """ Switch to the parent folder
        
        :param state: not used state object
        """
        if self.current_folder == self.separator:
            return

        self.switch_file_playback_mode()

        if self.current_folder and self.current_folder[-1] == self.separator:
            self.current_folder = self.current_folder[:-1]

        tmp = self.current_folder

        sep_index = self.current_folder.rfind(self.separator)
        self.browsing_history.pop(self.current_folder, None)

        folder = self.current_folder
        page_index = 0
        selected_item = None

        if sep_index == -1: return

        if sep_index != 0:
            folder = self.current_folder[0:sep_index]

            if len(self.browsing_history) == 0:
                page_index = -1
                selected_item = tmp
            else:
                page_index = self.browsing_history.get(folder, 0)
        elif sep_index == 0:
            folder = self.separator
            try:
                page_index = self.browsing_history[folder]
            except:
                pass

        try:
            self.change_folder(folder, page_index, selected=selected_item)
        except:
            pass

        if self.filelist.length != 0 and tmp != None:
            self.filelist.set_current_item_by_url(tmp)
            self.unselect()
            i = self.filelist.current_item_index
            self.select_by_index(i)

    def change_folder(self,
                      folder,
                      page_index=0,
                      playlist=None,
                      selected=None):
        """ Change folder
        
        :param folder: new folder name
        :param page_index: new page index
        :param playlist: playlist content
        """
        if not folder:
            if self.config[AUDIO][MUSIC_FOLDER]:
                folder = self.config[AUDIO][MUSIC_FOLDER]
            else:
                folder = self.util.file_util.current_folder

        self.current_folder = folder
        self.selected_index = None

        folder_content = playlist
        if not folder_content and self.config[CURRENT][MODE] != CD_PLAYER:
            folder_content = self.util.load_folder_content(
                folder, self.filelist.rows, self.filelist.columns,
                self.bounding_box)

        if not folder_content:
            self.buttons = {}
            self.components = []
        self.filelist = Page(folder_content, self.filelist.rows,
                             self.filelist.columns)

        if selected:
            self.filelist.set_current_item_by_url(selected)
            page_index = self.filelist.current_page_index

        self.browsing_history[folder] = page_index

        self.init_page(page_index)
        self.notify_change_folder_listeners(folder)
        self.update_buttons()
        self.draw()
        self.page_turned = True

    def select_first_item(self, state=None):
        """ Select the first item in menu """

        if self.filelist.length == 0: return

        self.filelist.set_current_item(0)
        self.unselect()
        self.select_by_index(0)

    def update_buttons(self):
        """ Update left/right buttons """

        left = str(self.filelist.get_left_items_number())
        right = str(self.filelist.get_right_items_number())
        self.notify_left_number_listeners(left)
        self.notify_right_number_listeners(right)

    def get_button_by_index_in_page(self, index):
        """ Return the button by its index on page
        
        :param index: button index
        :return: the button
        """
        for button in self.buttons.values():
            if button.state.comparator_item == index:
                return button
        return None

    def get_button_by_filename(self, file_name):
        """ Return the button by its file name
        
        :param file_name: file name
        :return: the button
        """
        for button in self.buttons.values():
            if button.state.file_name == file_name:
                return button
        return None

    def is_in_filelist(self, file_name):
        """ Check that file is in the current file list
        
        :param file_name: file name
        :return: True - in file list, False- not in file list
        """
        for item in self.filelist.items:
            if item.file_name == file_name:
                return True
        return False

    def get_button_by_index(self, index):
        """ Return the button by its index on page
        
        :param index: button index
        :return: the button
        """
        for button in self.buttons.values():
            if button.state.index == index:
                return button
        return None

    def draw(self):
        """ Draw menu """

        self.clean()
        self.select_by_index(self.selected_index)
        super(FileMenu, self).draw()
        self.update()

    def add_left_number_listener(self, listener):
        """ Add left button event listener
        
        :param listener: event listener
        """
        if listener not in self.left_number_listeners:
            self.left_number_listeners.append(listener)

    def notify_left_number_listeners(self, index):
        """ Notify left number button listeners
        
        :param index: file index
        """
        for listener in self.left_number_listeners:
            listener(index)

    def add_right_number_listener(self, listener):
        """ Add right button event listener
        
        :param listener: event listener
        """
        if listener not in self.right_number_listeners:
            self.right_number_listeners.append(listener)

    def notify_right_number_listeners(self, index):
        """ Notify right number button listeners
        
        :param index: file index
        """
        for listener in self.right_number_listeners:
            listener(index)

    def add_change_folder_listener(self, listener):
        """ Add change folder event listener
        
        :param listener: event listener
        """
        if listener not in self.change_folder_listeners:
            self.change_folder_listeners.append(listener)

    def notify_change_folder_listeners(self, state):
        """ Notify change folder listeners
        
        :param state: state object defining new folder
        """
        for listener in self.change_folder_listeners:
            listener(state)

    def add_play_file_listener(self, listener):
        """ Add play file event listener
        
        :param listener: event listener
        """
        if listener not in self.play_file_listeners:
            self.play_file_listeners.append(listener)

    def notify_play_file_listeners(self, state):
        """ Notify play file listeners
        
        :param state: state object defining file
        """
        for listener in self.play_file_listeners:
            listener(state)

    def add_playlist_size_listener(self, listener):
        """ Add playlist size event listener
        
        :param listener: event listener
        """
        if listener not in self.playlist_size_listeners:
            self.playlist_size_listeners.append(listener)

    def notify_playlist_size_listener(self, size):
        """ Notify playlist size listeners
        
        :param size: playlist size
        """
        for listener in self.playlist_size_listeners:
            listener(size)

    def add_menu_navigation_listeners(self, listener):
        """ Add menu navigation event listener
        
        :param listener: event listener
        """
        if listener not in self.menu_navigation_listeners:
            self.menu_navigation_listeners.append(listener)

    def notify_menu_navigation_listeners(self, state):
        """ Notify menu navigation listeners """

        for listener in self.menu_navigation_listeners:
            listener(state)
Beispiel #4
0
    def turn_page(self, state=None):
        """ Turn screen page
        
        :param state: button state
        """
        filelist = Page(self.episodes, MENU_ROWS_EPISODES,
                        MENU_COLUMNS_EPISODES)

        if state == None:
            filelist.current_page_index = self.current_page - 1
            index = filelist.current_page_index * PAGE_SIZE_EPISODES
        else:
            if getattr(state, "status", None) == STATUS_LOADED:
                if hasattr(state, "original_url") and len(
                        state.original_url.strip()) > 0:
                    filelist.set_current_item_by_url(state.original_url)
                else:
                    filelist.set_current_item_by_file_name(state.file_name)
            else:
                filelist.set_current_item_by_url(state.url)
            index = filelist.current_item_index

        self.current_page = filelist.current_page_index + 1

        page = filelist.get_current_page()
        d = self.episodes_menu.make_dict(page)
        self.episodes_menu.set_items(d, filelist.current_page_index,
                                     self.select_episode, False)
        self.set_title(self.current_page)
        self.episodes_menu.unselect()
        self.episodes_menu.select_by_index(index)

        self.navigator.left_button.change_label(
            str(filelist.get_left_items_number()))
        self.navigator.right_button.change_label(
            str(filelist.get_right_items_number()))
        self.episodes_menu.clean_draw_update()

        if hasattr(self, "update_observer"):
            self.episodes_menu.add_menu_observers(self.update_observer,
                                                  self.redraw_observer)
Beispiel #5
0
    def __init__(self, util, get_current_playlist, playlist_provider,
                 listeners, voice_assistant):
        """ Initializer
        
        :param util: utility object
        :param listeners: file browser listeners
        """
        self.util = util
        self.config = util.config
        self.factory = Factory(util)
        self.bounding_box = util.screen_rect
        layout = BorderLayout(self.bounding_box)
        layout.set_percent_constraints(PERCENT_TOP_HEIGHT,
                                       PERCENT_BOTTOM_HEIGHT, 0, 0)
        Screen.__init__(self, util, "", PERCENT_TOP_HEIGHT, voice_assistant,
                        "file_browser_screen_title", True, layout.TOP)
        current_folder = self.util.file_util.current_folder
        d = {"current_title": current_folder}

        if self.config[FILE_PLAYBACK][
                CURRENT_FILE_PLAYBACK_MODE] == FILE_PLAYLIST:
            f = self.config[FILE_PLAYBACK][CURRENT_FOLDER]
            p = self.config[FILE_PLAYBACK][CURRENT_FILE_PLAYLIST]
            d = f + os.sep + p

        self.screen_title.set_text(d)

        rows = self.config[FILE_BROWSER_ROWS]
        columns = self.config[FILE_BROWSER_COLUMNS]
        self.filelist = None
        playback_mode = self.config[FILE_PLAYBACK][CURRENT_FILE_PLAYBACK_MODE]

        if not playback_mode:
            self.config[FILE_PLAYBACK][
                CURRENT_FILE_PLAYBACK_MODE] = playback_mode = FILE_AUDIO

        button_box = pygame.Rect(0, 0, layout.CENTER.w / columns,
                                 layout.CENTER.h / rows)
        if self.config[ALIGN_BUTTON_CONTENT_X] == 'center':
            location = TOP
        else:
            location = self.config[ALIGN_BUTTON_CONTENT_X]
        icon_box = self.factory.get_icon_bounding_box(button_box, location,
                                                      self.config[IMAGE_AREA],
                                                      self.config[IMAGE_SIZE],
                                                      self.config[PADDING])
        icon_box_without_label = self.factory.get_icon_bounding_box(
            button_box, location, 100, 100, self.config[PADDING], False)

        if playback_mode == FILE_AUDIO or playback_mode == FILE_RECURSIVE:
            folder_content = self.util.load_folder_content(
                current_folder, rows, columns, icon_box,
                icon_box_without_label)
            self.filelist = Page(folder_content, rows, columns)
        elif playback_mode == FILE_PLAYLIST:
            s = State()
            s.folder = self.config[FILE_PLAYBACK][CURRENT_FOLDER]
            s.music_folder = self.config[AUDIO][MUSIC_FOLDER]
            s.file_name = self.config[FILE_PLAYBACK][CURRENT_FILE_PLAYLIST]

            pl = self.get_filelist_items(get_current_playlist)
            if len(pl) == 0:
                pl = self.util.load_playlist(s, playlist_provider, rows,
                                             columns, (icon_box.w, icon_box.h))
            else:
                pl = self.util.load_playlist_content(pl, rows, columns,
                                                     (icon_box.w, icon_box.h))
            self.filelist = Page(pl, rows, columns)

        self.file_menu = FileMenu(self.filelist, util, playlist_provider,
                                  layout.CENTER, location, icon_box,
                                  icon_box_without_label)
        self.file_menu.parent_screen = self
        self.file_menu.link_borders = self.link_borders

        self.file_menu.add_change_folder_listener(self.screen_title.set_text)
        self.file_menu.add_play_file_listener(listeners[KEY_PLAY_FILE])

        listeners[GO_LEFT_PAGE] = self.file_menu.page_down
        listeners[GO_RIGHT_PAGE] = self.file_menu.page_up
        listeners[GO_USER_HOME] = self.file_menu.switch_to_user_home
        listeners[GO_ROOT] = self.file_menu.switch_to_root
        listeners[GO_TO_PARENT] = self.file_menu.switch_to_parent_folder

        self.navigator = FileNavigator(util, layout.BOTTOM, listeners)
        left = str(self.filelist.get_left_items_number())
        right = str(self.filelist.get_right_items_number())
        left_button = self.navigator.get_button_by_name(KEY_PAGE_DOWN)
        right_button = self.navigator.get_button_by_name(KEY_PAGE_UP)
        self.back_button = self.navigator.get_button_by_name(KEY_BACK)
        left_button.change_label(left)
        right_button.change_label(right)

        self.file_menu.add_left_number_listener(left_button.change_label)
        self.file_menu.add_right_number_listener(right_button.change_label)
        self.add_navigator(self.navigator)
        self.page_turned = False
        self.animated_title = True

        self.file_menu.navigator = self.navigator
        self.add_menu(self.file_menu)
        self.link_borders()
        self.back_button.set_selected(True)
Beispiel #6
0
class FileBrowserScreen(Screen):
    """ File Browser Screen """
    def __init__(self, util, get_current_playlist, playlist_provider,
                 listeners, voice_assistant):
        """ Initializer
        
        :param util: utility object
        :param listeners: file browser listeners
        """
        self.util = util
        self.config = util.config
        self.factory = Factory(util)
        self.bounding_box = util.screen_rect
        layout = BorderLayout(self.bounding_box)
        layout.set_percent_constraints(PERCENT_TOP_HEIGHT,
                                       PERCENT_BOTTOM_HEIGHT, 0, 0)
        Screen.__init__(self, util, "", PERCENT_TOP_HEIGHT, voice_assistant,
                        "file_browser_screen_title", True, layout.TOP)
        current_folder = self.util.file_util.current_folder
        d = {"current_title": current_folder}

        if self.config[FILE_PLAYBACK][
                CURRENT_FILE_PLAYBACK_MODE] == FILE_PLAYLIST:
            f = self.config[FILE_PLAYBACK][CURRENT_FOLDER]
            p = self.config[FILE_PLAYBACK][CURRENT_FILE_PLAYLIST]
            d = f + os.sep + p

        self.screen_title.set_text(d)

        rows = self.config[FILE_BROWSER_ROWS]
        columns = self.config[FILE_BROWSER_COLUMNS]
        self.filelist = None
        playback_mode = self.config[FILE_PLAYBACK][CURRENT_FILE_PLAYBACK_MODE]

        if not playback_mode:
            self.config[FILE_PLAYBACK][
                CURRENT_FILE_PLAYBACK_MODE] = playback_mode = FILE_AUDIO

        button_box = pygame.Rect(0, 0, layout.CENTER.w / columns,
                                 layout.CENTER.h / rows)
        if self.config[ALIGN_BUTTON_CONTENT_X] == 'center':
            location = TOP
        else:
            location = self.config[ALIGN_BUTTON_CONTENT_X]
        icon_box = self.factory.get_icon_bounding_box(button_box, location,
                                                      self.config[IMAGE_AREA],
                                                      self.config[IMAGE_SIZE],
                                                      self.config[PADDING])
        icon_box_without_label = self.factory.get_icon_bounding_box(
            button_box, location, 100, 100, self.config[PADDING], False)

        if playback_mode == FILE_AUDIO or playback_mode == FILE_RECURSIVE:
            folder_content = self.util.load_folder_content(
                current_folder, rows, columns, icon_box,
                icon_box_without_label)
            self.filelist = Page(folder_content, rows, columns)
        elif playback_mode == FILE_PLAYLIST:
            s = State()
            s.folder = self.config[FILE_PLAYBACK][CURRENT_FOLDER]
            s.music_folder = self.config[AUDIO][MUSIC_FOLDER]
            s.file_name = self.config[FILE_PLAYBACK][CURRENT_FILE_PLAYLIST]

            pl = self.get_filelist_items(get_current_playlist)
            if len(pl) == 0:
                pl = self.util.load_playlist(s, playlist_provider, rows,
                                             columns, (icon_box.w, icon_box.h))
            else:
                pl = self.util.load_playlist_content(pl, rows, columns,
                                                     (icon_box.w, icon_box.h))
            self.filelist = Page(pl, rows, columns)

        self.file_menu = FileMenu(self.filelist, util, playlist_provider,
                                  layout.CENTER, location, icon_box,
                                  icon_box_without_label)
        self.file_menu.parent_screen = self
        self.file_menu.link_borders = self.link_borders

        self.file_menu.add_change_folder_listener(self.screen_title.set_text)
        self.file_menu.add_play_file_listener(listeners[KEY_PLAY_FILE])

        listeners[GO_LEFT_PAGE] = self.file_menu.page_down
        listeners[GO_RIGHT_PAGE] = self.file_menu.page_up
        listeners[GO_USER_HOME] = self.file_menu.switch_to_user_home
        listeners[GO_ROOT] = self.file_menu.switch_to_root
        listeners[GO_TO_PARENT] = self.file_menu.switch_to_parent_folder

        self.navigator = FileNavigator(util, layout.BOTTOM, listeners)
        left = str(self.filelist.get_left_items_number())
        right = str(self.filelist.get_right_items_number())
        left_button = self.navigator.get_button_by_name(KEY_PAGE_DOWN)
        right_button = self.navigator.get_button_by_name(KEY_PAGE_UP)
        self.back_button = self.navigator.get_button_by_name(KEY_BACK)
        left_button.change_label(left)
        right_button.change_label(right)

        self.file_menu.add_left_number_listener(left_button.change_label)
        self.file_menu.add_right_number_listener(right_button.change_label)
        self.add_navigator(self.navigator)
        self.page_turned = False
        self.animated_title = True

        self.file_menu.navigator = self.navigator
        self.add_menu(self.file_menu)
        self.link_borders()
        self.back_button.set_selected(True)

    def get_filelist_items(self, get_current_playlist):
        """ Call player for files in the playlist 
        
        :return: list of files from playlist
        """
        playlist = get_current_playlist()
        files = []
        if playlist:
            for n in range(len(playlist)):
                st = State()
                st.index = st.comparator_item = n
                st.file_type = FILE_AUDIO
                st.file_name = st.url = playlist[n]
                files.append(st)
        return files

    def add_screen_observers(self, update_observer, redraw_observer):
        """ Add screen observers
        
        :param update_observer: observer for updating the screen
        :param redraw_observer: observer to redraw the whole screen
        """
        Screen.add_screen_observers(self, update_observer, redraw_observer)

        self.file_menu.add_menu_observers(update_observer,
                                          redraw_observer,
                                          release=False)
        self.file_menu.add_change_folder_listener(redraw_observer)
        self.file_menu.add_menu_navigation_listeners(redraw_observer)

        self.file_menu.add_left_number_listener(redraw_observer)
        self.file_menu.add_right_number_listener(redraw_observer)

        self.navigator.add_observers(update_observer, redraw_observer)

    def handle_event(self, event):
        """ Handle screen event

        :param event: the event to handle
        """
        if event.type == USER_EVENT_TYPE and event.sub_type == SUB_TYPE_KEYBOARD and (
                event.action == pygame.KEYUP
                or event.action == pygame.KEYDOWN):
            menu_selected = self.file_menu.get_selected_index()
            navigator_selected = self.navigator.is_selected()

            if menu_selected != None:
                self.file_menu.handle_event(event)
            elif navigator_selected:
                self.navigator.handle_event(event)
        else:
            Screen.handle_event(self, event)
Beispiel #7
0
 def __init__(self, util, get_current_playlist, playlist_provider, listeners, voice_assistant):
     """ Initializer
     
     :param util: utility object
     :param listeners: file browser listeners
     """
     self.util = util
     self.config = util.config
     self.factory = Factory(util)
     self.bounding_box = util.screen_rect
     layout = BorderLayout(self.bounding_box)
     layout.set_percent_constraints(PERCENT_TOP_HEIGHT, PERCENT_BOTTOM_HEIGHT, 0, 0)
     Screen.__init__(self, util, "", PERCENT_TOP_HEIGHT, voice_assistant, "file_browser_screen_title", True, layout.TOP)
     color_dark_light = self.config[COLORS][COLOR_DARK_LIGHT]
     current_folder = self.util.file_util.current_folder  
     d = {"current_title" : current_folder}
     
     if self.config[FILE_PLAYBACK][CURRENT_FILE_PLAYBACK_MODE] == FILE_PLAYLIST:
         f = self.config[FILE_PLAYBACK][CURRENT_FOLDER]
         p = self.config[FILE_PLAYBACK][CURRENT_FILE_PLAYLIST]
         d = f + os.sep + p
     
     self.screen_title.set_text(d)
     
     rows = 3
     columns = 3
     self.filelist = None
     playback_mode = self.config[FILE_PLAYBACK][CURRENT_FILE_PLAYBACK_MODE]
     
     if not playback_mode:
         self.config[FILE_PLAYBACK][CURRENT_FILE_PLAYBACK_MODE] = playback_mode = FILE_AUDIO
     
     if playback_mode == FILE_AUDIO or playback_mode == FILE_RECURSIVE:
         folder_content = self.util.load_folder_content(current_folder, rows, columns, layout.CENTER)  
         self.filelist = Page(folder_content, rows, columns)
     elif playback_mode == FILE_PLAYLIST:
         s = State()
         s.folder = self.config[FILE_PLAYBACK][CURRENT_FOLDER]
         s.music_folder = self.config[AUDIO][MUSIC_FOLDER]
         s.file_name = self.config[FILE_PLAYBACK][CURRENT_FILE_PLAYLIST]
         
         pl = self.get_filelist_items(get_current_playlist)
         if len(pl) == 0:            
             pl = self.util.load_playlist(s, playlist_provider, rows, columns)
         else:
             pl = self.util.load_playlist_content(pl, rows, columns)
         self.filelist = Page(pl, rows, columns)
     
     self.file_menu = FileMenu(self.filelist, util, playlist_provider, (0, 0, 0), layout.CENTER)
     
     Container.add_component(self, self.file_menu)
     self.file_menu.add_change_folder_listener(self.screen_title.set_text)
     self.file_menu.add_play_file_listener(listeners[KEY_PLAY_FILE])
     
     listeners[GO_LEFT_PAGE] = self.file_menu.page_down
     listeners[GO_RIGHT_PAGE] = self.file_menu.page_up
     listeners[GO_USER_HOME] = self.file_menu.switch_to_user_home
     listeners[GO_ROOT] = self.file_menu.switch_to_root
     listeners[GO_TO_PARENT] = self.file_menu.switch_to_parent_folder
     
     self.navigator = Navigator(util, layout.BOTTOM, listeners, color_dark_light)
     left = str(self.filelist.get_left_items_number())
     right = str(self.filelist.get_right_items_number())
     self.navigator.left_button.change_label(left)
     self.navigator.right_button.change_label(right)
     
     self.file_menu.add_left_number_listener(self.navigator.left_button.change_label)
     self.file_menu.add_right_number_listener(self.navigator.right_button.change_label)
     Container.add_component(self, self.navigator)
     self.page_turned = False    
Beispiel #8
0
class FileBrowserScreen(Screen):
    """ File Browser Screen """
    
    def __init__(self, util, get_current_playlist, playlist_provider, listeners, voice_assistant):
        """ Initializer
        
        :param util: utility object
        :param listeners: file browser listeners
        """
        self.util = util
        self.config = util.config
        self.factory = Factory(util)
        self.bounding_box = util.screen_rect
        layout = BorderLayout(self.bounding_box)
        layout.set_percent_constraints(PERCENT_TOP_HEIGHT, PERCENT_BOTTOM_HEIGHT, 0, 0)
        Screen.__init__(self, util, "", PERCENT_TOP_HEIGHT, voice_assistant, "file_browser_screen_title", True, layout.TOP)
        color_dark_light = self.config[COLORS][COLOR_DARK_LIGHT]
        current_folder = self.util.file_util.current_folder  
        d = {"current_title" : current_folder}
        
        if self.config[FILE_PLAYBACK][CURRENT_FILE_PLAYBACK_MODE] == FILE_PLAYLIST:
            f = self.config[FILE_PLAYBACK][CURRENT_FOLDER]
            p = self.config[FILE_PLAYBACK][CURRENT_FILE_PLAYLIST]
            d = f + os.sep + p
        
        self.screen_title.set_text(d)
        
        rows = 3
        columns = 3
        self.filelist = None
        playback_mode = self.config[FILE_PLAYBACK][CURRENT_FILE_PLAYBACK_MODE]
        
        if not playback_mode:
            self.config[FILE_PLAYBACK][CURRENT_FILE_PLAYBACK_MODE] = playback_mode = FILE_AUDIO
        
        if playback_mode == FILE_AUDIO or playback_mode == FILE_RECURSIVE:
            folder_content = self.util.load_folder_content(current_folder, rows, columns, layout.CENTER)  
            self.filelist = Page(folder_content, rows, columns)
        elif playback_mode == FILE_PLAYLIST:
            s = State()
            s.folder = self.config[FILE_PLAYBACK][CURRENT_FOLDER]
            s.music_folder = self.config[AUDIO][MUSIC_FOLDER]
            s.file_name = self.config[FILE_PLAYBACK][CURRENT_FILE_PLAYLIST]
            
            pl = self.get_filelist_items(get_current_playlist)
            if len(pl) == 0:            
                pl = self.util.load_playlist(s, playlist_provider, rows, columns)
            else:
                pl = self.util.load_playlist_content(pl, rows, columns)
            self.filelist = Page(pl, rows, columns)
        
        self.file_menu = FileMenu(self.filelist, util, playlist_provider, (0, 0, 0), layout.CENTER)
        
        Container.add_component(self, self.file_menu)
        self.file_menu.add_change_folder_listener(self.screen_title.set_text)
        self.file_menu.add_play_file_listener(listeners[KEY_PLAY_FILE])
        
        listeners[GO_LEFT_PAGE] = self.file_menu.page_down
        listeners[GO_RIGHT_PAGE] = self.file_menu.page_up
        listeners[GO_USER_HOME] = self.file_menu.switch_to_user_home
        listeners[GO_ROOT] = self.file_menu.switch_to_root
        listeners[GO_TO_PARENT] = self.file_menu.switch_to_parent_folder
        
        self.navigator = Navigator(util, layout.BOTTOM, listeners, color_dark_light)
        left = str(self.filelist.get_left_items_number())
        right = str(self.filelist.get_right_items_number())
        self.navigator.left_button.change_label(left)
        self.navigator.right_button.change_label(right)
        
        self.file_menu.add_left_number_listener(self.navigator.left_button.change_label)
        self.file_menu.add_right_number_listener(self.navigator.right_button.change_label)
        Container.add_component(self, self.navigator)
        self.page_turned = False    
    
    def get_filelist_items(self, get_current_playlist):
        """ Call player for files in the playlist 
        
        :return: list of files from playlist
        """
        playlist = get_current_playlist()
        files = []
        if playlist:
            for n in range(len(playlist)):
                st = State()
                st.index = st.comparator_item = n
                st.file_type = FILE_AUDIO
                st.file_name = st.url = playlist[n]
                files.append(st)
        return files
    
    def add_screen_observers(self, update_observer, redraw_observer):
        """ Add screen observers
        
        :param update_observer: observer for updating the screen
        :param redraw_observer: observer to redraw the whole screen
        """
        Screen.add_screen_observers(self, update_observer, redraw_observer)
        
        self.file_menu.add_menu_observers(update_observer, redraw_observer=None, release=False)        
        self.file_menu.add_change_folder_listener(redraw_observer)
        self.file_menu.add_menu_navigation_listeners(redraw_observer)
        
        self.file_menu.add_left_number_listener(redraw_observer)
        self.file_menu.add_right_number_listener(redraw_observer)       
        
        self.navigator.add_observers(update_observer, redraw_observer)
Beispiel #9
0
    def __init__(self, listeners, util, voice_assistant, screen_mode=STATION):
        """ Initializer
        
        :param util: utility object
        :param listener: screen menu event listener
        """
        self.util = util
        self.config = util.config
        self.factory = Factory(util)
        self.screen_mode = screen_mode
        self.bounding_box = util.screen_rect
        self.favorites_util = FavoritesUtil(self.util)
        layout = BorderLayout(self.bounding_box)
        k = self.bounding_box.w / self.bounding_box.h
        percent_menu_width = (100.0 - PERCENT_TOP_HEIGHT -
                              PERCENT_BOTTOM_HEIGHT) / k
        panel_width = (100.0 - percent_menu_width) / 2.0
        layout.set_percent_constraints(PERCENT_TOP_HEIGHT,
                                       PERCENT_BOTTOM_HEIGHT, panel_width,
                                       panel_width)
        Screen.__init__(self, util, "", PERCENT_TOP_HEIGHT, voice_assistant,
                        "station_screen_title", True, layout.TOP)

        tmp = Menu(util, (0, 0, 0), self.bounding_box, None, None)
        folders = self.util.get_stations_folders()
        if folders:
            panel_layout = BorderLayout(layout.RIGHT)
            panel_layout.set_percent_constraints(PERCENT_SIDE_BOTTOM_HEIGHT,
                                                 PERCENT_SIDE_BOTTOM_HEIGHT, 0,
                                                 0)
            self.genres = util.load_stations_folders(panel_layout.BOTTOM)
            self.genres[
                KEY_FAVORITES] = self.favorites_util.get_favorites_button_state(
                    panel_layout.BOTTOM)
            current_genre_name = list(self.genres.keys())[0]
            self.current_genre = self.genres[current_genre_name]
        self.items_per_line = self.items_per_line(layout.CENTER.w)
        items = []
        if self.screen_mode == STATION:
            k = STATIONS + "." + self.config[CURRENT][LANGUAGE]
            try:
                self.config[k]
                self.current_genre = self.genres[self.config[k]
                                                 [CURRENT_STATIONS]]
            except:
                self.config[k] = {}
                self.config[k][CURRENT_STATIONS] = self.current_genre.name
            items = self.load_stations(
                self.config[CURRENT][LANGUAGE], self.current_genre.name,
                self.items_per_line * self.items_per_line)
        elif self.screen_mode == STREAM:
            items = util.load_streams(self.items_per_line *
                                      self.items_per_line)

        self.playlist = Page(items, self.items_per_line, self.items_per_line)

        self.station_menu = StationMenu(self.playlist, util, screen_mode,
                                        (0, 0, 0), layout.CENTER)
        if self.station_menu.is_button_defined():
            d = {"current_title": self.station_menu.button.state.l_name}
            self.screen_title.set_text(d)
        Container.add_component(self, self.station_menu)

        self.stop_player = listeners[KEY_STOP]
        self.create_left_panel(layout, listeners)
        self.create_right_panel(layout, listeners)

        self.home_button.add_release_listener(listeners[KEY_HOME])
        if self.screen_mode == STATION:
            self.genres_button.add_release_listener(listeners[KEY_GENRES])
        self.shutdown_button.add_release_listener(
            self.favorites_util.save_favorites)
        self.shutdown_button.add_release_listener(listeners[KEY_SHUTDOWN])
        self.left_button.add_release_listener(
            self.station_menu.switch_to_previous_station)
        self.left_button.add_release_listener(self.update_arrow_button_labels)
        self.page_down_button.add_release_listener(
            self.station_menu.switch_to_previous_page)
        self.page_down_button.add_release_listener(
            self.update_arrow_button_labels)
        self.right_button.add_release_listener(
            self.station_menu.switch_to_next_station)
        self.right_button.add_release_listener(self.update_arrow_button_labels)
        self.page_up_button.add_release_listener(
            self.station_menu.switch_to_next_page)
        self.page_up_button.add_release_listener(
            self.update_arrow_button_labels)
        self.station_menu.add_listener(listeners[KEY_PLAY])
        self.station_menu.add_listener(self.screen_title.set_state)
        self.station_menu.add_listener(self.update_arrow_button_labels)
        self.station_menu.add_mode_listener(self.mode_listener)

        self.volume = self.factory.create_volume_control(layout.BOTTOM)
        self.volume.add_slide_listener(listeners[KEY_SET_VOLUME])
        self.volume.add_slide_listener(listeners[KEY_SET_CONFIG_VOLUME])
        self.volume.add_slide_listener(listeners[KEY_SET_SAVER_VOLUME])
        self.volume.add_knob_listener(listeners[KEY_MUTE])
        Container.add_component(self, self.volume)
        self.player_screen = True

        if self.current_genre.name == KEY_FAVORITES:
            self.favorites_mode = True
        else:
            self.favorites_mode = False

        self.favorites_util.set_favorites_in_config(self.items_per_line)
Beispiel #10
0
    def set_current(self, state=None):
        """ Set current station by index defined in current playlist 
        
        :param state: button state (if any)
        """
        items = []
        current_language = self.config[CURRENT][LANGUAGE]
        selected_genre = None
        self.favorites_mode = False

        if self.screen_mode == STATION:
            key = STATIONS + "." + current_language
            s1 = state != None and getattr(state, "source",
                                           None) == KEY_FAVORITES
            s2 = state == None and self.config[key][
                CURRENT_STATIONS] == KEY_FAVORITES
            if s1 or s2:
                self.favorites_mode = True
                self.config[key][CURRENT_STATIONS] = KEY_FAVORITES

            try:
                k = self.config[key][CURRENT_STATIONS]
                selected_genre = self.genres[k]
                self.store_previous_station(current_language)
            except:
                self.config[key] = {}
                selected_genre = self.current_genre

            genre = selected_genre.name
            size = self.items_per_line * self.items_per_line
            items = self.load_stations(current_language, genre, size)
        elif self.screen_mode == STREAM:
            items = self.util.load_streams(self.items_per_line *
                                           self.items_per_line)

        self.playlist = Page(items, self.items_per_line, self.items_per_line)

        if self.playlist.length == 0:
            return

        self.station_menu.set_playlist(self.playlist)

        if self.screen_mode == STATION:
            self.station_menu.genre = selected_genre.name
            previous_station_index = 0
            try:
                previous_station_index = self.config[
                    STATIONS + "." + current_language][selected_genre.name]
            except KeyError:
                pass
            self.station_menu.set_station(previous_station_index)
            self.station_menu.set_station_mode(None)
            self.set_genre_button_image(selected_genre)

            if self.favorites_mode:
                self.current_genre = self.favorites_util.get_favorites_button_state(
                    self.genres_button.state.bounding_box)
            else:
                self.current_genre = selected_genre
        elif self.screen_mode == STREAM:
            previous_station_index = 0
            try:
                previous_station_index = self.config[CURRENT][STREAM]
            except KeyError:
                pass
            self.station_menu.set_station(previous_station_index)
            self.station_menu.set_station_mode(None)
            self.config[CURRENT][STREAM] = previous_station_index
        n = self.station_menu.get_current_station_name()
        self.screen_title.set_text(n)

        config_volume_level = int(self.config[PLAYER_SETTINGS][VOLUME])
        if self.volume.get_position() != config_volume_level:
            self.volume.set_position(config_volume_level)
            self.volume.update_position()
Beispiel #11
0
    def __init__(self, listeners, util, voice_assistant, screen_mode=STATION):
        """ Initializer
        
        :param util: utility object
        :param listener: screen menu event listener
        """
        self.util = util
        self.config = util.config
        self.factory = Factory(util)
        self.screen_mode = screen_mode
        self.bounding_box = util.screen_rect
        self.favorites_util = FavoritesUtil(self.util)

        self.top_height = self.config[PLAYER_SCREEN][TOP_HEIGHT_PERCENT]
        self.bottom_height = self.config[PLAYER_SCREEN][BOTTOM_HEIGHT_PERCENT]
        self.button_height = self.config[PLAYER_SCREEN][BUTTON_HEIGHT_PERCENT]
        self.popup_width = self.config[PLAYER_SCREEN][POPUP_WIDTH_PERCENT]
        self.image_location = self.config[PLAYER_SCREEN][IMAGE_LOCATION]

        self.layout = self.get_layout()
        Screen.__init__(self, util, "", self.top_height, voice_assistant,
                        "station_screen_title", True, self.layout.TOP)
        self.layout = self.get_layout()

        folders = self.util.get_stations_folders()
        if folders:
            panel_layout = self.get_panel_layout(self.layout, LOCATION_RIGHT)
            panel_layout.set_percent_constraints(self.button_height,
                                                 self.button_height, 0, 0)
            self.genres = util.load_stations_folders(panel_layout.BOTTOM)
            self.genres[
                KEY_FAVORITES] = self.favorites_util.get_favorites_button_state(
                    panel_layout.BOTTOM)
            current_genre_name = list(self.genres.keys())[0]
            self.current_genre = self.genres[current_genre_name]
        self.items_per_line = self.items_per_line(self.layout.CENTER.w)
        items = []
        if self.screen_mode == STATION:
            k = STATIONS + "." + self.config[CURRENT][LANGUAGE]
            try:
                self.config[k]
                self.current_genre = self.genres[self.config[k]
                                                 [CURRENT_STATIONS]]
            except:
                self.config[k] = {}
                self.config[k][CURRENT_STATIONS] = self.current_genre.name
            items = self.load_stations(
                self.config[CURRENT][LANGUAGE], self.current_genre.name,
                self.items_per_line * self.items_per_line)
        elif self.screen_mode == STREAM:
            items = util.load_streams(self.items_per_line *
                                      self.items_per_line)

        self.playlist = Page(items, self.items_per_line, self.items_per_line)

        self.station_menu = StationMenu(
            self.playlist, util, screen_mode,
            self.config[BACKGROUND][SCREEN_BGR_COLOR], self.layout.CENTER)
        if self.station_menu.is_button_defined():
            d = {"current_title": self.station_menu.button.state.l_name}
            self.screen_title.set_text(d)
        Container.add_component(self, self.station_menu)

        self.stop_player = listeners[KEY_STOP]
        self.create_left_panel(self.layout, listeners)
        self.create_right_panel(self.layout, listeners)

        self.home_button.add_release_listener(listeners[KEY_HOME])
        if self.screen_mode == STATION:
            self.genres_button.add_release_listener(listeners[KEY_GENRES])
        self.shutdown_button.add_release_listener(
            self.favorites_util.save_favorites)
        self.shutdown_button.add_release_listener(listeners[KEY_SHUTDOWN])
        self.left_button.add_release_listener(
            self.station_menu.switch_to_previous_station)
        self.left_button.add_release_listener(self.update_arrow_button_labels)
        self.page_down_button.add_release_listener(
            self.station_menu.switch_to_previous_page)
        self.page_down_button.add_release_listener(
            self.update_arrow_button_labels)
        self.right_button.add_release_listener(
            self.station_menu.switch_to_next_station)
        self.right_button.add_release_listener(self.update_arrow_button_labels)
        self.page_up_button.add_release_listener(
            self.station_menu.switch_to_next_page)
        self.page_up_button.add_release_listener(
            self.update_arrow_button_labels)
        self.station_menu.add_listener(listeners[KEY_PLAY])
        self.station_menu.add_listener(self.screen_title.set_state)
        self.station_menu.add_listener(self.update_arrow_button_labels)
        self.station_menu.add_mode_listener(self.mode_listener)

        self.info_button = None
        self.info_popup = None
        self.start_screensaver = listeners[SCREENSAVER]
        bottom_layout = BorderLayout(self.layout.BOTTOM)
        bottom_layout.set_percent_constraints(0, 0, 0, self.popup_width)

        volume_layout = bottom_layout.CENTER
        volume_layout.w -= 2
        volume_layout.x += 1

        self.volume = self.factory.create_volume_control(volume_layout)
        self.volume.add_slide_listener(listeners[KEY_SET_VOLUME])
        self.volume.add_slide_listener(listeners[KEY_SET_CONFIG_VOLUME])
        self.volume.add_slide_listener(listeners[KEY_SET_SAVER_VOLUME])
        self.volume.add_knob_listener(listeners[KEY_MUTE])
        self.add_component(self.volume)
        self.player_screen = True

        self.add_popup(bottom_layout.RIGHT)

        if self.current_genre.name == KEY_FAVORITES:
            self.favorites_mode = True
        else:
            self.favorites_mode = False

        self.favorites_util.set_favorites_in_config(self.items_per_line)
        self.animated_title = True
Beispiel #12
0
class FileMenu(Menu):
    """ File Menu class. Extends base Menu class """
    
    def __init__(self, filelist, util, playlist_provider, bounding_box=None, align=ALIGN_CENTER, icon_box=None, icon_box_without_label=None):
        """ Initializer
        
        :param filelist: file list
        :param util: utility object
        :param bgr: menu background
        :param bounding_box: bounding box
        """
        self.factory = Factory(util)
        self.util = util
        self.cdutil = CdUtil(self.util)
        self.playlist_provider = playlist_provider
        self.config = self.util.config
        self.filelist = filelist
        self.icon_box = icon_box
        self.icon_box_without_label = icon_box_without_label

        m = self.create_file_menu_button
        self.bounding_box = bounding_box
        bgr = util.config[BACKGROUND][MENU_BGR_COLOR]
        
        r = c = 3
        if filelist:
            r = filelist.rows
            c = filelist.columns

        h = self.config[HORIZONTAL_LAYOUT]
        button_height = (self.bounding_box.h / r) - (self.config[PADDING] * 2)

        if self.config[ALIGN_BUTTON_CONTENT_X] == 'center':
            font_size = int(((100 - self.config[IMAGE_AREA]) / 100) * self.config[FONT_HEIGHT_PERCENT])
        else:
            font_size = int((button_height / 100) * self.config[FONT_HEIGHT_PERCENT])

        Menu.__init__(self, util, bgr, self.bounding_box, r, c, create_item_method=m, align=align, horizontal_layout=h, font_size=font_size)

        self.browsing_history = {}        
        self.left_number_listeners = []
        self.right_number_listeners = []
        self.change_folder_listeners = []
        self.play_file_listeners = []
        self.playlist_size_listeners = []
        self.menu_navigation_listeners = []
        self.page_turned = False
        self.separator = os.sep
        self.empty_state = State()
        url = selection = None
        self.current_folder = self.config[FILE_PLAYBACK][CURRENT_FOLDER]
        folder = self.current_folder

        playback_mode = self.config[FILE_PLAYBACK][CURRENT_FILE_PLAYBACK_MODE]
        if playback_mode == FILE_AUDIO or playback_mode == FILE_RECURSIVE:
            if not self.current_folder.endswith(os.sep):
                self.current_folder += os.sep                
                        
            if self.config[CURRENT][MODE] == CD_PLAYER:
                cd_drive_name = self.config[CD_PLAYBACK][CD_DRIVE_NAME]
                track = self.config[CD_PLAYBACK][CD_TRACK]
                url = self.cdutil.get_cd_track_url(cd_drive_name, track)
            else:
                url = self.current_folder + self.config[FILE_PLAYBACK][CURRENT_FILE]                            
        elif playback_mode == FILE_PLAYLIST:
            url = self.config[FILE_PLAYBACK][CURRENT_FILE]
            self.browsing_history[self.current_folder] = 0
            p = self.current_folder + self.separator + self.config[FILE_PLAYBACK][CURRENT_FILE_PLAYLIST]
            self.browsing_history[p] = 0
            folder = p
            self.current_folder = folder
        selection = url
        
        if url and self.filelist:        
            self.filelist.set_current_item_by_url(url)
        
        p_index = self.filelist.current_page_index
        pl = self.filelist.items
        self.change_folder(folder, page_index=p_index, playlist=pl, selected=selection)            
    
    def create_file_menu_button(self, s, constr, action, scale, font_size):
        """ Create File Menu button

        :param s: button state
        :param constr: scaling constraints
        :param action: button event listener
        :param scale: True - scale images, False - don't scale images

        :return: file menu button
        """
        scale = False
        s.padding = self.config[PADDING]
        s.image_area_percent = self.config[IMAGE_AREA]
        label_area_percent = 100 - s.image_area_percent
        if self.config[ALIGN_BUTTON_CONTENT_X] == 'left':
            s.image_location = LEFT
            s.label_location = LEFT
            s.h_align = H_ALIGN_LEFT
        elif self.config[ALIGN_BUTTON_CONTENT_X] == 'right':
            s.image_location = RIGHT
            s.label_location = RIGHT
            s.h_align = H_ALIGN_RIGHT
        elif self.config[ALIGN_BUTTON_CONTENT_X] == 'center':
            s.image_location = TOP
            s.label_location = BOTTOM
            s.h_align = H_ALIGN_CENTER
        s.v_align = CENTER
        s.wrap_labels = self.config[WRAP_LABELS]
        s.fixed_height = font_size

        if s.file_type == FOLDER_WITH_ICON or (s.file_type == FILE_AUDIO and getattr(s, "has_embedded_image", None)):
            scale = True
        if hasattr(s, "show_label"):
            return self.factory.create_menu_button(s, constr, action, scale, label_area_percent=label_area_percent, show_label=s.show_label, font_size=font_size)
        else:
            return self.factory.create_menu_button(s, constr, action, scale, label_area_percent=label_area_percent, font_size=font_size)

    def recursive_change_folder(self, state):
        """ Change recursive folder
        
        :param state: state object
        """
        f = self.util.file_util.get_first_folder_with_audio_files(state.url)
        if f == None:
            self.change_folder(state.url)
            return
        
        self.config[FILE_PLAYBACK][CURRENT_FILE_PLAYBACK_MODE] = FILE_RECURSIVE
        
        self.config[FILE_PLAYBACK][CURRENT_FOLDER] = f[0]
        state.folder = f[0]
        state.file_name = f[1]
        state.file_type = FILE_AUDIO
        state.url = os.path.join(f[0], f[1])
        self.change_folder(f[0])
        self.handle_file(state)
        
    def select_item(self, state):
        """ Select menu item
        
        :param state: state object defining selected object
        """ 
        if self.visible:
            if state.file_type == FILE_AUDIO or state.file_type == FILE_PLAYLIST:
                self.config[FILE_PLAYBACK][CURRENT_FOLDER] = self.util.file_util.current_folder
                if self.config[FILE_PLAYBACK][CURRENT_FILE_PLAYBACK_MODE] == FILE_PLAYLIST:
                    if hasattr(state, "file_name") and hasattr(state, "name"):
                        file_name = state.file_name
                        name = state.name
                        index = file_name.rfind(name)
                        if index != -1:
                            folder = file_name[0 : index]
                            if len(folder.strip()) > 0:
                                self.config[FILE_PLAYBACK][CURRENT_FOLDER] = folder
        
        if state.file_type == FOLDER or state.file_type == FOLDER_WITH_ICON:
            if getattr(state, "long_press", False):
                if self.config[FILE_PLAYBACK][CURRENT_FILE_PLAYBACK_MODE] == FILE_RECURSIVE:
                    self.config[FILE_PLAYBACK][CURRENT_FILE_PLAYBACK_MODE] = FILE_AUDIO
                    self.change_folder(state.url)
                else:
                    self.config[FILE_PLAYBACK][CURRENT_FILE_PLAYLIST] = state.url
                    self.recursive_change_folder(state)
            else:
                self.config[FILE_PLAYBACK][CURRENT_FILE_PLAYBACK_MODE] = FILE_AUDIO  
                self.change_folder(state.url)
        elif state.file_type == FILE_AUDIO:
            if getattr(state, "long_press", False) and self.config[FILE_PLAYBACK][CURRENT_FILE_PLAYBACK_MODE] == FILE_RECURSIVE:
                self.config[FILE_PLAYBACK][CURRENT_FILE_PLAYBACK_MODE] = FILE_AUDIO
            
            m = getattr(state, "playback_mode", FILE_AUDIO)
            mode = self.config[FILE_PLAYBACK][CURRENT_FILE_PLAYBACK_MODE] or FILE_AUDIO
            if m == FILE_AUDIO and mode == FILE_AUDIO:
                self.handle_file(state)
            else:
                self.config[FILE_PLAYBACK][CURRENT_FILE] = state.file_name
                self.config[FILE_PLAYBACK][CURRENT_TRACK_TIME] = None
                if not getattr(state, "dont_notify", None):            
                    self.notify_play_file_listeners(state)
                else:
                    n = self.config[AUDIO][CLIENT_NAME]
                    if n == VLC or n == MPV:
                        self.handle_file(state)
            self.handle_border_links()
        elif state.file_type == FILE_PLAYLIST:
            self.config[FILE_PLAYBACK][CURRENT_FILE_PLAYBACK_MODE] = FILE_PLAYLIST
            i = state.url.rfind(self.separator)
            url = state.url[i + 1:]
            self.config[FILE_PLAYBACK][CURRENT_FILE_PLAYLIST] = url
            state.music_folder = self.config[AUDIO][MUSIC_FOLDER]
            pl = self.util.load_playlist(state, self.playlist_provider, self.filelist.rows, self.filelist.columns, (self.icon_box.w, self.icon_box.h))
            url = state.url
            if pl:
                self.notify_playlist_size_listener(len(pl))
            else:
                url = state.url[0 : i]
            u = getattr(state, "url", None)            
            if u == None:
                state.url = state.folder + os.sep + state.file_name
                url = state.url
                                
            self.change_folder(url, playlist=pl)
            
        if self.visible:
            self.draw()
   
    def page_up(self, state=None):
        """ Called by page up button
        
        :param state: not used
        """        
        if self.filelist.length <= self.filelist.items_per_page:
            return
        
        self.switch_to_next_page(None)
        
    def page_down(self, state=None):
        """ Called by page down button
        
        :param state: not used
        """        
        if self.filelist.length <= self.filelist.items_per_page:
            return
        
        self.switch_to_previous_page(None)
   
    def handle_file(self, state):
        """ Handle audio file
        
        :param state: state object defining audio file
        """
        
        state.track_time = '0'
        
        if not state.file_name.startswith("cdda:"):
            self.config[FILE_PLAYBACK][CURRENT_FILE] = state.file_name
            self.config[FILE_PLAYBACK][CURRENT_TRACK_TIME] = state.track_time
        
        if self.is_in_filelist(state.file_name):
            b = self.get_button_by_filename(state.file_name)
            if not b:
                self.switch_to_next_page(state)
            else:
                state.comparator_item = b.state.comparator_item
        
        if not self.config[FILE_PLAYBACK][CURRENT_FILE].startswith("cdda:"):
            if not self.config[FILE_PLAYBACK][CURRENT_FOLDER].endswith(os.sep):
                url = self.config[FILE_PLAYBACK][CURRENT_FOLDER] + os.sep + self.config[FILE_PLAYBACK][CURRENT_FILE]
            else:
                url = self.config[FILE_PLAYBACK][CURRENT_FOLDER] + self.config[FILE_PLAYBACK][CURRENT_FILE]
            self.filelist.set_current_item_by_url(url)
        
        mode = getattr(state, "playback_mode", None)
        if mode == None:
            if state.file_type == FILE_AUDIO:
                state.playback_mode = FILE_AUDIO
            else:
                state.playback_mode = FILE_PLAYLIST

        self.item_selected(state)
        if not getattr(state, "dont_notify", None):
            self.notify_play_file_listeners(state)
    
    def update_playlist_menu(self, state):
        """ Update playlist menu
        This is initiated by player
        
        :param state: state object from player defining current playlist file
        """
        if self.config[FILE_PLAYBACK][CURRENT_FILE_PLAYBACK_MODE] != FILE_PLAYLIST:
            return 
        
        s = State()
        s.dont_notify = True
        
        i = self.util.get_dictionary_value(state, "current_track_id")
        s.track_time = self.util.get_dictionary_value(state, "seek_time", "0")
        self.config[FILE_PLAYBACK][CURRENT_TRACK_TIME] = s.track_time
        
        if i != None:            
            b = self.get_button_by_index_in_page(int(i) - 1)
            if not b:
                self.switch_to_next_page(s)
            s.comparator_item = int(i) 
            
        name = self.util.get_dictionary_value(state, "Track")
        
        if not name:
            name = self.util.get_dictionary_value(state, "file_name")
        
        if name != None:
            self.config[FILE_PLAYBACK][CURRENT_FILE] = name
        
        self.item_selected(state)
    
    def get_comparator(self, state):
        """ Return comparator object from state
        
        :param state: state object containing comparator item
        """
        try:
            p = state["Pos"]
            return int(p)
        except:
            pass
        
        try:
            s_comp = getattr(state, "comparator_item", None)
            if s_comp != None:
                return s_comp
        except:
            pass
        
        s_name = None
        
        if isinstance(state, dict):
            try:
                s_name = state["file_name"]
            except:
                pass
        elif isinstance(state, State):
            s_name = getattr(state, "file_name", None)
        
        for button in self.buttons.values():            
            b_name = getattr(button.state, "file_name", None)
            if s_name and b_name and s_name == button.state.file_name:
                return button.state.comparator_item
        return None
    
    def set_current_folder(self, folder):
        """ Current folder setter
        
        :param folder: new current folder
        """
        self.current_folder = folder
    
    def set_filelist(self, filelist):
        """ Set filelist
        
        :param filelist: the filelist to set
        """
        self.filelist = filelist        
    
    def init_page(self, index):
        """ Page initializer
        
        :param index: new current page index
        """
        url = self.config[FILE_PLAYBACK][CURRENT_FILE]
        if self.config[FILE_PLAYBACK][CURRENT_FILE_PLAYBACK_MODE] == FILE_AUDIO:  
            url = self.config[FILE_PLAYBACK][CURRENT_FOLDER] + os.sep + self.config[FILE_PLAYBACK][CURRENT_FILE]
            
        if url:
            self.filelist.set_current_item_by_url(url)
            
        self.filelist.current_page_index = index        
        page = self.filelist.get_current_page()
        self.set_page(self.filelist.current_item_index_in_page, page)
        
        if not self.filelist.current_item:
            self.filelist.current_page_index = index

    def set_page(self, index_on_page, page, align=ALIGN_CENTER):
        """ Page setter
        
        :param index_on_page: current item index on page
        :param page: current page content
        """
        if page == None: return
        
        self.set_items(self.make_dict(page), index_on_page, self.select_item)

        for b in self.buttons.values():
            b.parent_screen = self.parent_screen

        self.draw() 

    def switch_to_next_page(self, state):
        """ Switch to the next page
        
        :param state: button state
        """
        if len(self.filelist.items) == 0:
            return
        self.turn_page(state, self.filelist.next_page())
            
    def switch_to_previous_page(self, state):
        """ Switch to the previous page
        
        :param state: button state
        """
        if len(self.filelist.items) == 0:
            return        
        self.turn_page(state, self.filelist.previous_page())
        
    def turn_page(self, state, page):
        """ Change current page
        
        :param state: state object defining current item on page
        :param page: new page content
        """
        self.set_page(self.filelist.current_item_index, page)
        if getattr(state, "url", None):
            self.filelist.set_current_item_by_url(state.url)
        if self.visible:
            self.item_selected(self.filelist.current_item)        
        self.update_buttons()
        if not getattr(state, "dont_notify", None):
            self.draw()            
        self.page_turned = True
        
        f = self.current_folder
        
        if f[-1] == self.separator:
            f = f[:-1]

        self.browsing_history[f] = self.filelist.current_page_index
        self.handle_border_links()
    
    def handle_border_links(self):
        """ Handle border links and menu/navigator selection """

        if hasattr(self, "link_borders"):
            self.link_borders()

        if hasattr(self, "navigator"):
            if self.get_selected_item() != None:
                self.navigator.unselect()
            else:
                if not self.navigator.is_selected():
                    b = self.navigator.get_button_by_name(KEY_HOME)
                    b.set_selected(True)
                    b.clean_draw_update()

    def switch_to_root(self, state):
        """ Switch to the root folder
        
        :param state: not used state object
        """
        self.switch_folder(self.util.file_util.ROOT)
            
    def switch_to_user_home(self, state):
        """ Switch to the user home folder
        
        :param state: not used state object
        """
        self.switch_folder(self.util.file_util.USER_HOME)  
    
    def switch_folder(self, folder):
        """ Switch to folder
        
        :param folder: folder to switch to
        """
        self.switch_file_playback_mode()
        self.change_folder(folder)
    
    def switch_file_playback_mode(self):
        if self.config[FILE_PLAYBACK][CURRENT_FILE_PLAYBACK_MODE] == FILE_PLAYLIST:
            self.config[FILE_PLAYBACK][CURRENT_FILE_PLAYBACK_MODE] = FILE_AUDIO
    
    def switch_to_parent_folder(self, state):
        """ Switch to the parent folder
        
        :param state: not used state object
        """
        if self.current_folder == self.separator:
            return
        
        self.switch_file_playback_mode()
        
        if self.current_folder and self.current_folder[-1] == self.separator:
            self.current_folder = self.current_folder[:-1]

        tmp = self.current_folder    
        
        sep_index = self.current_folder.rfind(self.separator)
        self.browsing_history.pop(self.current_folder, None)
        
        folder = self.current_folder
        page_index = 0 
        selected_item = tmp
        
        if sep_index == -1: return
        
        if sep_index != 0:
            folder = self.current_folder[0:sep_index]
            
            if len(self.browsing_history) == 0:
                page_index = -1
            else:
                page_index = self.browsing_history.get(folder, 0)
        elif sep_index == 0:
            folder = self.separator            
            try:
                page_index = self.browsing_history[folder]
            except:
                pass
            
        try:
            self.change_folder(folder, page_index, selected=selected_item)
        except:
            pass
                    
        if self.filelist.length != 0 and tmp != None:
            self.filelist.set_current_item_by_url(tmp)
            self.unselect()
            i = self.filelist.current_item_index
            self.select_by_index(i)
            if hasattr(self, "navigator") and self.get_selected_item() != None:
                self.navigator.unselect()
    
    def change_folder(self, folder, page_index=0, playlist=None, selected=None):
        """ Change folder
        
        :param folder: new folder name
        :param page_index: new page index
        :param playlist: playlist content
        """
        if not folder:
            if self.config[AUDIO][MUSIC_FOLDER]:
                folder = self.config[AUDIO][MUSIC_FOLDER]
            else:
                folder = self.util.file_util.current_folder        
        
        self.current_folder = folder
        self.selected_index = None
        
        folder_content = playlist
        if not folder_content and self.config[CURRENT][MODE] != CD_PLAYER:
            folder_content = self.util.load_folder_content(folder, self.filelist.rows, self.filelist.columns, self.icon_box, self.icon_box_without_label)
            
        if not folder_content:
            self.buttons = {}
            self.components = []            
        self.filelist = Page(folder_content, self.filelist.rows, self.filelist.columns)

        if selected:
            self.filelist.set_current_item_by_url(selected)
            page_index = self.filelist.current_item_page_index

        self.browsing_history[folder] = page_index 
        self.init_page(page_index)
        self.notify_change_folder_listeners(folder)
        self.update_buttons()
        self.page_turned = True

        self.handle_border_links()               
    
    def update_buttons(self):
        """ Update left/right buttons """
        
        left = str(self.filelist.get_left_items_number())
        right = str(self.filelist.get_right_items_number())        
        self.notify_left_number_listeners(left)
        self.notify_right_number_listeners(right)    
            
    def get_button_by_index_in_page(self, index):
        """ Return the button by its index on page
        
        :param index: button index
        :return: the button
        """
        for button in self.buttons.values():
            if button.state.comparator_item == index:
                return button
        return None
    
    def get_button_by_filename(self, file_name):
        """ Return the button by its file name
        
        :param file_name: file name
        :return: the button
        """
        for button in self.buttons.values():
            if button.state.file_name == file_name:
                return button
        return None
    
    def is_in_filelist(self, file_name):
        """ Check that file is in the current file list
        
        :param file_name: file name
        :return: True - in file list, False- not in file list
        """
        if not self.filelist.items:
            return False

        for item in self.filelist.items:
            if item.file_name == file_name:
                return True
        return False
    
    def get_button_by_index(self, index):
        """ Return the button by its index on page
        
        :param index: button index
        :return: the button
        """
        for button in self.buttons.values():
            if button.state.index == index:
                return button
        return None
    
    def draw(self):
        """ Draw menu """
        
        self.clean()
        super(FileMenu, self).draw()        
        self.update()
     
    def add_left_number_listener(self, listener):
        """ Add left button event listener
        
        :param listener: event listener
        """
        if listener not in self.left_number_listeners:
            self.left_number_listeners.append(listener)     
 
    def notify_left_number_listeners(self, index):
        """ Notify left number button listeners
        
        :param index: file index
        """
        for listener in self.left_number_listeners:
            listener(index)
            
    def add_right_number_listener(self, listener):
        """ Add right button event listener
        
        :param listener: event listener
        """
        if listener not in self.right_number_listeners:
            self.right_number_listeners.append(listener)     
 
    def notify_right_number_listeners(self, index):
        """ Notify right number button listeners
        
        :param index: file index
        """
        for listener in self.right_number_listeners:
            listener(index)
            
    def add_change_folder_listener(self, listener):
        """ Add change folder event listener
        
        :param listener: event listener
        """
        if listener not in self.change_folder_listeners:
            self.change_folder_listeners.append(listener)     
 
    def notify_change_folder_listeners(self, state):
        """ Notify change folder listeners
        
        :param state: state object defining new folder
        """
        for listener in self.change_folder_listeners:
            listener(state)
            
    def add_play_file_listener(self, listener):
        """ Add play file event listener
        
        :param listener: event listener
        """
        if listener not in self.play_file_listeners:
            self.play_file_listeners.append(listener)     
 
    def notify_play_file_listeners(self, state):
        """ Notify play file listeners
        
        :param state: state object defining file
        """
        for listener in self.play_file_listeners:
            listener(state)
            
    def add_playlist_size_listener(self, listener):
        """ Add playlist size event listener
        
        :param listener: event listener
        """
        if listener not in self.playlist_size_listeners:
            self.playlist_size_listeners.append(listener)     
 
    def notify_playlist_size_listener(self, size):
        """ Notify playlist size listeners
        
        :param size: playlist size
        """
        for listener in self.playlist_size_listeners:
            listener(size)
            
    def add_menu_navigation_listeners(self, listener):
        """ Add menu navigation event listener
        
        :param listener: event listener
        """
        if listener not in self.menu_navigation_listeners:
            self.menu_navigation_listeners.append(listener)     
 
    def notify_menu_navigation_listeners(self, state):
        """ Notify menu navigation listeners """
        
        for listener in self.menu_navigation_listeners:
            listener(state)