예제 #1
0
    def __init__(self, listeners, util):
        """ Initializer
        
        :param util: utility object
        :param listener: screen menu event listener
        """
        self.util = util
        self.config = util.config
        Container.__init__(self, util, background=(0, 0, 0))
        self.factory = Factory(util)
        self.bounding_box = self.config[SCREEN_RECT]
        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)
        self.genres = util.load_menu(GENRE_ITEMS, GENRE)        
        self.current_genre = self.genres[self.config[CURRENT][PLAYLIST]]
        self.items_per_line = self.items_per_line(layout.CENTER.w)
        self.playlist = Playlist(self.config[CURRENT][LANGUAGE], self.current_genre.genre, util, self.items_per_line)
        
        font_size = (layout.TOP.h * PERCENT_TITLE_FONT)/100.0
        color_dark = self.config[COLORS][COLOR_DARK]
        color_contrast = self.config[COLORS][COLOR_CONTRAST]
        self.screen_title = self.factory.create_dynamic_text("station_screen_title", layout.TOP, color_dark, color_contrast, int(font_size))
        Container.add_component(self, self.screen_title)

        self.station_menu = StationMenu(self.playlist, util, (0, 0, 0), layout.CENTER)
        self.screen_title.set_text(self.station_menu.button.state.l_name)        
        Container.add_component(self, self.station_menu)
        
        self.create_left_panel(layout, listeners)
        self.create_right_panel(layout, listeners)        

        self.home_button.add_release_listener(listeners["go home"])
        self.genres_button.add_release_listener(listeners["go genres"])
        self.shutdown_button.add_release_listener(listeners["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["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["set volume"])
        self.volume.add_slide_listener(listeners["set config volume"])
        self.volume.add_slide_listener(listeners["set screensaver volume"])
        self.volume.add_knob_listener(listeners["mute"])        
        Container.add_component(self, self.volume)
예제 #2
0
class Screen(Container):
    """ Base class for all screens. Extends Container class """
    
    def __init__(self, util, title_key):
        """ Initializer
        
        :param util: utility object
        :param title_key: the resource bundle key for the screen title
        """
        Container.__init__(self, util)
        self.util = util
        factory = Factory(util)
        config = util.config
        self.bounding_box = config[SCREEN_RECT]
        self.bgr = (0, 0, 0)
        self.layout = BorderLayout(config[SCREEN_RECT])
        self.layout.set_percent_constraints(PERCENT_TOP_HEIGHT, 0, 0, 0)

        font_size = (self.layout.TOP.h * PERCENT_TITLE_FONT)/100.0
        d = config[COLORS][COLOR_DARK]
        c = config[COLORS][COLOR_CONTRAST]
        self.screen_title = factory.create_output_text("screen_title", self.layout.TOP, d, c, int(font_size))
        label = config[LABELS][title_key]
        self.screen_title.set_text(label) 
        self.add_component(self.screen_title)
        
    def add_menu(self, menu):
        """ Add menu to the screen
        
        :param menu: the menu to add
        """
        self.menu = menu
        self.add_component(menu)
        
    def get_clickable_rect(self):
        """ Return the list of rectangles which define the clickable areas on screen. Used for web browser. 
        
        :return: list of rectangles
        """
        c = Component(self.util)
        c.name = "clickable_rect"
        c.content = self.menu.bounding_box
        c.bgr = c.fgr = (0, 0, 0)
        c.content_x = c.content_y = 0
        d = [c]       
        return d
예제 #3
0
 def create_left_panel(self, layout, listeners):
     """ Create Station Screen left panel. Include Shutdown button, Left button and Home button.
     
     :param layout: left panel layout
     :param listeners: event listeners
     """
     panel_layout = BorderLayout(layout.LEFT)
     panel_layout.set_percent_constraints(PERCENT_SIDE_BOTTOM_HEIGHT, PERCENT_SIDE_BOTTOM_HEIGHT, 0, 0)
     left = self.station_menu.button.state.index
     self.left_button = self.factory.create_left_button(panel_layout.CENTER, str(left))
     self.page_down_button = self.factory.create_page_down_button(panel_layout.CENTER, str(left))
     self.page_down_button.set_visible(False)
     self.shutdown_button = self.factory.create_shutdown_button(panel_layout.TOP)
     self.home_button = self.factory.create_home_button(panel_layout.BOTTOM)
     panel = Container(self.util, layout.LEFT)
     panel.add_component(self.shutdown_button)
     panel.add_component(self.left_button)
     panel.add_component(self.page_down_button)
     panel.add_component(self.home_button)
     Container.add_component(self, panel)
예제 #4
0
 def create_right_panel(self, layout, listeners):
     """ Create Station Screen right panel. Include Genre button, right button and Play/Pause button
     
     :param layout: right panel layout
     :param listeners: event listeners
     """
     panel_layout = BorderLayout(layout.RIGHT)
     panel_layout.set_percent_constraints(PERCENT_SIDE_BOTTOM_HEIGHT, PERCENT_SIDE_BOTTOM_HEIGHT, 0, 0)
     self.genres_button = self.factory.create_genre_button(panel_layout.TOP, self.current_genre)
     right = self.playlist.length - self.station_menu.button.state.index - 1 
     self.right_button = self.factory.create_right_button(panel_layout.CENTER, str(right))
     self.page_up_button = self.factory.create_page_up_button(panel_layout.CENTER, str(right))
     self.page_up_button.set_visible(False)
     self.play_button = self.factory.create_play_pause_button(panel_layout.BOTTOM, listeners["play-pause"])  
     panel = Container(self.util, layout.RIGHT)
     panel.add_component(self.genres_button)
     panel.add_component(self.right_button)
     panel.add_component(self.page_up_button)
     panel.add_component(self.play_button)
     Container.add_component(self, panel)
예제 #5
0
    def __init__(self, util, title_key):
        """ Initializer
        
        :param util: utility object
        :param title_key: the resource bundle key for the screen title
        """
        Container.__init__(self, util)
        self.util = util
        factory = Factory(util)
        config = util.config
        self.bounding_box = config[SCREEN_RECT]
        self.bgr = (0, 0, 0)
        self.layout = BorderLayout(config[SCREEN_RECT])
        self.layout.set_percent_constraints(PERCENT_TOP_HEIGHT, 0, 0, 0)

        font_size = (self.layout.TOP.h * PERCENT_TITLE_FONT)/100.0
        d = config[COLORS][COLOR_DARK]
        c = config[COLORS][COLOR_CONTRAST]
        self.screen_title = factory.create_output_text("screen_title", self.layout.TOP, d, c, int(font_size))
        label = config[LABELS][title_key]
        self.screen_title.set_text(label) 
        self.add_component(self.screen_title)
예제 #6
0
class Screen(Container):
    """ Base class for all screens. Extends Container class """
    def __init__(self,
                 util,
                 title_key,
                 percent_bottom_height=0,
                 voice_assistant=None,
                 screen_title_name="screen_title",
                 create_dynamic_title=False,
                 title_layout=None,
                 title=None):
        """ Initializer
        
        :param util: utility object
        :param title_key: the resource bundle key for the screen title
        """
        Container.__init__(self, util)
        self.util = util
        factory = Factory(util)
        self.config = util.config
        self.bounding_box = util.screen_rect
        self.bgr = (0, 0, 0)
        self.layout = BorderLayout(util.screen_rect)
        self.layout.set_percent_constraints(PERCENT_TOP_HEIGHT,
                                            percent_bottom_height, 0, 0)
        self.voice_assistant = voice_assistant

        self.font_size = int((self.layout.TOP.h * PERCENT_TITLE_FONT) / 100.0)
        d = self.config[COLORS][COLOR_DARK_LIGHT]
        c = self.config[COLORS][COLOR_CONTRAST]

        t_layout = self.layout.TOP
        if title_layout:
            t_layout = title_layout

        if create_dynamic_title:
            self.screen_title = factory.create_dynamic_text(
                screen_title_name, t_layout, d, c, self.font_size)
        else:
            self.screen_title = factory.create_output_text(
                screen_title_name, t_layout, d, c, self.font_size)

        if title:
            self.screen_title.set_text(title)
        else:
            if title_key and len(title_key) > 0:
                try:
                    label = self.config[LABELS][title_key]
                    self.screen_title.set_text(label)
                except:
                    pass

        if voice_assistant:
            self.screen_title.add_select_listener(self.handle_voice_assistant)
            self.layout.TOP.w += 1
            self.voice_command = factory.create_output_text(
                "voice_command", self.layout.TOP, d, c, self.font_size)
            self.voice_command.add_select_listener(self.handle_voice_assistant)
            self.voice_assistant.add_text_recognized_listener(
                self.text_recognized)
            self.voice_assistant.assistant.add_start_conversation_listener(
                self.start_conversation)
            self.voice_assistant.assistant.add_stop_conversation_listener(
                self.stop_conversation)

        if voice_assistant and voice_assistant.is_running():
            self.title_selected = False
        else:
            self.title_selected = True

        self.draw_title_bar()
        self.player_screen = False
        self.update_web_observer = None
        self.update_web_title = None

        self.loading_listeners = []
        self.LOADING = util.config[LABELS][KEY_LOADING]
        self.factory = factory

    def draw_title_bar(self):
        """ Draw title bar on top of the screen """

        if len(self.components) != 0 and self.title_selected:
            self.components[0] = self.voice_command
            self.title_selected = False
        elif len(self.components) != 0 and not self.title_selected:
            self.components[0] = self.screen_title
            self.title_selected = True
        elif len(self.components) == 0 and self.title_selected:
            self.components.append(self.screen_title)
        elif len(self.components) == 0 and not self.title_selected:
            self.voice_command.set_text(
                self.config[LABELS][KEY_WAITING_FOR_COMMAND])
            self.components.append(self.voice_command)

    def handle_voice_assistant(self, state=None):
        """ Start/Stop voice assistant 
        
        :state: not used
        """
        if self.title_selected:
            self.voice_assistant.start()
        else:
            self.voice_assistant.stop()

    def text_recognized(self, text):
        """ Handle text recognized event 
        
        :text: recognized text
        """
        c = self.config[LABELS][KEY_VA_COMMAND] + " " + text
        self.voice_command.set_text(c)
        self.voice_command.clean_draw_update()
        time.sleep(self.config[VOICE_ASSISTANT][VOICE_COMMAND_DISPLAY_TIME])
        if self.update_web_title:
            self.update_web_title(self.voice_command)

    def start_conversation(self, event):
        """ Start voice conversation
        
        :event: not used
        """
        if self.visible:
            self.voice_command.set_visible(True)
        self.voice_command.set_text_no_draw(
            self.config[LABELS][KEY_WAITING_FOR_COMMAND])
        self.components[0] = self.voice_command
        self.title_selected = False
        if self.visible:
            self.voice_command.clean_draw_update()
            if self.update_web_observer:
                self.update_web_observer()

    def stop_conversation(self):
        """ Stop voice conversation """

        if self.visible:
            self.screen_title.set_visible(True)
        self.components[0] = self.screen_title
        self.title_selected = True
        if self.visible:
            self.screen_title.clean_draw_update()
            if self.update_web_observer:
                self.update_web_observer()

    def add_menu(self, menu):
        """ Add menu to the screen
        
        :param menu: the menu to add
        """
        self.menu = menu
        self.add_component(menu)

    def enable_player_screen(self, flag):
        """ Enable player screen
        
        :param flag: enable/disable flag
        """
        pass

    def exit_screen(self):
        """ Complete actions required to save screen state """

        self.set_visible(False)

    def add_screen_observers(self,
                             update_observer,
                             redraw_observer,
                             title_to_json=None):
        """ Add screen observers.
        
        :param update_observer: observer for updating the screen
        :param redraw_observer: observer to redraw the whole screen
        """
        self.update_web_observer = redraw_observer
        self.update_web_title = title_to_json

    def set_loading(self, name=None, menu_bb=None, text=None):
        """ Show Loading... sign

        :param name: screen title
        :param menu_bb: menu bounding box
        :param text: screen text
        """
        b = self.config[COLORS][COLOR_DARK]
        f = self.config[COLORS][COLOR_BRIGHT]
        fs = int(self.bounding_box.h * 0.07)

        if menu_bb != None:
            bb = menu_bb
        else:
            bb = self.bounding_box

        t = self.factory.create_output_text(self.LOADING, bb, b, f, fs)
        if not text:
            t.set_text(self.LOADING)
        else:
            t.set_text(text)

        if name != None:
            self.screen_title.set_text(name)

        self.set_visible(True)
        self.add_component(t)
        self.clean_draw_update()
        self.notify_loading_listeners()

    def reset_loading(self):
        """ Remove Loading label """

        del self.components[-1]
        self.notify_loading_listeners()

    def add_loading_listener(self, listener):
        """ Add loading listener

        :param listener: event listener
        """
        if listener not in self.loading_listeners:
            self.loading_listeners.append(listener)

    def notify_loading_listeners(self):
        """ Notify all loading listeners """

        for listener in self.loading_listeners:
            listener(None)
예제 #7
0
 def __init__(self, state):
     """ Initializer. Define bounding boxes for button label (if any) and icon (if any)
     
     :param state: button state
     """        
     s = state
     bb = s.bounding_box
     self.show_image = getattr(s, "show_img", None)
     self.show_label = getattr(s, "show_label", False)
     self.image_location = getattr(s, "image_location", CENTER)
     self.label_location = getattr(s, "label_location", BOTTOM)
     self.image_area_percent = getattr(s, "image_area_percent", 0)
     self.label_area_percent = getattr(s, "label_area_percent", 0)        
     self.layout = BorderLayout(bb)
     top = bottom = left = right = 0
     self.image_rectangle = self.label_rectangle = None
     
     if self.show_image and self.show_label:
         if self.image_location == TOP and self.label_location == CENTER:
             top = self.image_area_percent
             self.layout.set_percent_constraints(top, bottom, left, right)
             self.image_rectangle = self.layout.TOP
             self.label_rectangle = self.layout.CENTER
         elif self.image_location == BOTTOM and self.label_location == CENTER:
             bottom = self.image_area_percent
             self.layout.set_percent_constraints(top, bottom, left, right)
             self.image_rectangle = self.layout.BOTTOM
             self.label_rectangle = self.layout.CENTER
         elif self.image_location == CENTER and self.label_location == TOP:
             top = self.label_area_percent
             self.layout.set_percent_constraints(top, bottom, left, right)
             self.image_rectangle = self.layout.CENTER
             self.label_rectangle = self.layout.TOP
         elif self.image_location == CENTER and self.label_location == BOTTOM:
             bottom = self.label_area_percent
             self.layout.set_percent_constraints(top, bottom, left, right)
             self.image_rectangle = self.layout.CENTER
             self.label_rectangle = self.layout.BOTTOM                
         elif self.image_location == LEFT and self.label_location == CENTER:
             left = self.image_area_percent
             self.layout.set_percent_constraints(top, bottom, left, right)
             self.image_rectangle = self.layout.LEFT
             self.label_rectangle = self.layout.CENTER
         elif self.image_location == RIGHT and self.label_location == CENTER:
             right = self.image_area_percent
             self.layout.set_percent_constraints(top, bottom, left, right)
             self.image_rectangle = self.layout.RIGHT
             self.label_rectangle = self.layout.CENTER
         elif self.image_location == CENTER and self.label_location == LEFT:
             left = self.label_area_percent
             self.layout.set_percent_constraints(top, bottom, left, right)
             self.image_rectangle = self.layout.CENTER
             self.label_rectangle = self.layout.LEFT
         elif self.image_location == CENTER and self.label_location == RIGHT:
             right = self.label_area_percent
             self.layout.set_percent_constraints(top, bottom, left, right)
             self.image_rectangle = self.layout.CENTER
             self.label_rectangle = self.layout.RIGHT
     elif self.show_image and not self.show_label:
         self.layout.set_percent_constraints(top, bottom, left, right)
         self.image_rectangle = self.layout.CENTER
     elif not self.show_image and self.show_label:
         self.layout.set_percent_constraints(top, bottom, left, right)
         self.label_rectangle = self.layout.CENTER
예제 #8
0
class FilePlayerScreen(Screen):
    """ File Player Screen """
    def __init__(self,
                 listeners,
                 util,
                 get_current_playlist,
                 voice_assistant,
                 player_stop=None):
        """ Initializer
        
        :param listeners: screen listeners
        :param util: utility object         
        """
        self.util = util
        self.config = util.config
        self.cdutil = CdUtil(util)
        self.factory = Factory(util)
        self.stop_player = player_stop
        self.get_current_playlist = get_current_playlist
        self.bounding_box = self.config[SCREEN_RECT]
        self.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
        self.layout.set_percent_constraints(PERCENT_TOP_HEIGHT,
                                            PERCENT_BOTTOM_HEIGHT, panel_width,
                                            panel_width)
        self.voice_assistant = voice_assistant
        Screen.__init__(self, util, "", PERCENT_TOP_HEIGHT, voice_assistant,
                        "file_player_screen_title", True, self.layout.TOP)
        self.layout = BorderLayout(self.bounding_box)
        self.layout.set_percent_constraints(PERCENT_TOP_HEIGHT,
                                            PERCENT_BOTTOM_HEIGHT, panel_width,
                                            panel_width)

        self.create_left_panel(self.layout, listeners)
        self.create_right_panel(self.layout, listeners)

        self.file_button = self.factory.create_file_button(
            self.layout.CENTER, listeners[AUDIO_FILES])

        Container.add_component(self, self.file_button)
        self.audio_files = self.get_audio_files()
        self.home_button.add_release_listener(listeners[KEY_HOME])
        self.shutdown_button.add_release_listener(listeners[KEY_SHUTDOWN])
        self.left_button.add_release_listener(self.go_left)
        self.right_button.add_release_listener(self.go_right)

        self.volume = self.factory.create_volume_control(self.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])
        self.volume_visible = False
        self.volume.set_visible(self.volume_visible)
        Container.add_component(self, self.volume)

        self.time_control = self.factory.create_time_control(
            self.layout.BOTTOM)
        self.time_control.add_seek_listener(listeners[KEY_SEEK])

        self.play_button.add_listener(PAUSE, self.time_control.pause)
        self.play_button.add_listener(KEY_PLAY, self.time_control.resume)
        self.left_button.add_release_listener(
            self.play_button.draw_default_state)
        self.right_button.add_release_listener(
            self.play_button.draw_default_state)

        if self.config[PLAYER_SETTINGS][PAUSE]:
            self.time_control.pause()

        Container.add_component(self, self.time_control)

        self.play_listeners = []
        self.add_play_listener(listeners[KEY_PLAY])

        self.current_folder = self.config[FILE_PLAYBACK][CURRENT_FOLDER]
        self.file_button.state.cover_art_folder = self.util.file_util.get_cover_art_folder(
            self.current_folder)
        self.playlist_size = 0
        self.player_screen = True
        self.cd_album = None

    def get_audio_files(self):
        """ Return the list of audio files in current folder
        
        :return: list of audio files
        """
        files = []
        if self.config[CURRENT][MODE] == CD_PLAYER:
            af = getattr(self, "audio_files", None)
            if af == None:
                cd_drive_name = self.config[CD_PLAYBACK][CD_DRIVE_NAME]
                files = self.cdutil.get_cd_tracks_summary(cd_drive_name)
            else:
                return self.audio_files
        else:
            folder = self.config[FILE_PLAYBACK][CURRENT_FOLDER]
            files = self.util.get_audio_files_in_folder(folder)

        return files

    def get_current_track_index(self, state=None):
        """ Return current track index.
        In case of files goes through the file list.
        In case of playlist takes track index from the state object.
        
        :return: current track index
        """
        if self.config[CURRENT][MODE] == AUDIOBOOKS:
            t = None
            try:
                t = state["file_name"]
            except:
                pass

            if t == None:
                try:
                    t = state["current_title"]
                except:
                    pass

            if t == None:
                try:
                    t = state
                except:
                    pass

            for i, f in enumerate(self.audio_files):
                try:
                    s = f["file_name"]
                except:
                    pass

                if getattr(f, "file_name", None):
                    s = getattr(f, "file_name", None)

                if s.endswith(t):
                    return i
            return 0

        mode = self.config[FILE_PLAYBACK][CURRENT_FILE_PLAYBACK_MODE]
        if state and mode == FILE_PLAYLIST:
            try:
                n = state["Track"]
                if n: return int(n) - 1
            except:
                pass

        if self.config[CURRENT][MODE] == CD_PLAYER:
            cmp = int(self.config[CD_PLAYBACK][CD_TRACK]) - 1
        else:
            cmp = self.config[FILE_PLAYBACK][CURRENT_FILE]
            if state and isinstance(state, State):
                cmp = state.file_name

        for f in self.audio_files:
            if self.config[CURRENT][MODE] == CD_PLAYER:
                if f.index == cmp:
                    return f.index
            else:
                if f.file_name == cmp:
                    return f.index
        return 0

    def stop_recursive_playback(self):
        """ Stop recursive playback """

        self.config[FILE_PLAYBACK][CURRENT_FILE_PLAYBACK_MODE] = FILE_AUDIO
        self.config[FILE_PLAYBACK][CURRENT_FILE_PLAYLIST] = None
        self.config[FILE_PLAYBACK][CURRENT_TRACK_TIME] = None
        self.stop_timer()
        self.time_control.stop_thread()
        self.time_control.reset()
        if self.stop_player != None:
            self.stop_player()

    def go_left(self, state):
        """ Switch to the previous track
        
        :param state: not used state object
        """
        if getattr(self, "current_track_index", None) == None:
            return

        filelist_size = self.get_filelist_size()

        if self.config[FILE_PLAYBACK][
                CURRENT_FILE_PLAYBACK_MODE] == FILE_RECURSIVE:
            self.stop_recursive_playback()
            return

        if self.current_track_index == 0:
            self.current_track_index = filelist_size - 1
        else:
            self.current_track_index -= 1
        self.change_track(self.current_track_index)

    def go_right(self, state):
        """ Switch to the next track
        
        :param state: not used state object
        """
        if getattr(self, "current_track_index", None) == None:
            return

        filelist_size = self.get_filelist_size()

        if self.config[FILE_PLAYBACK][
                CURRENT_FILE_PLAYBACK_MODE] == FILE_RECURSIVE and self.current_track_index == filelist_size - 1:
            self.stop_timer()
            self.time_control.stop_thread()
            self.recursive_change_folder()
            self.current_track_index = 0
            self.change_track(self.current_track_index)
            self.file_button.clean_draw_update()
            return

        if self.current_track_index == filelist_size - 1:
            self.current_track_index = 0
        else:
            self.current_track_index += 1

        self.change_track(self.current_track_index)

    def get_filelist_size(self):
        """ Return the file list size
        
        :return: file list size
        """
        if self.audio_files:
            return len(self.audio_files)
        else:
            return 0

    def change_track(self, track_index):
        """ Change track
        
        :param track_index: index track
        """
        a = [AUDIOBOOKS, CD_PLAYER]
        m = self.config[CURRENT][MODE]
        if not (m in a):
            self.config[FILE_PLAYBACK][CURRENT_FILE] = self.get_filename(
                track_index)

        self.stop_timer()
        time.sleep(0.3)
        s = State()
        if m == FILE_PLAYBACK:
            s.playback_mode = self.config[FILE_PLAYBACK][
                CURRENT_FILE_PLAYBACK_MODE]

        s.playlist_track_number = track_index
        s.index = track_index
        s.source = ARROW_BUTTON
        s.file_name = self.get_filename(track_index)

        if self.cd_album != None:
            s.album = self.cd_album

        self.set_current(True, s)

    def stop_timer(self):
        """ Stop time control timer """

        self.time_control.stop_timer()

    def get_filename(self, index):
        """ Get filename by index
        
        :param index: file index
        
        :return: filename
        """
        for b in self.audio_files:
            if b.index == index:
                return b.file_name
        return ""

    def is_valid_mode(self):
        current_mode = self.config[CURRENT][MODE]
        modes = [AUDIO_FILES, AUDIOBOOKS, CD_PLAYER]
        if current_mode in modes:
            return True
        else:
            return False

    def update_arrow_button_labels(self, state=None):
        """ Update left/right arrow button labels
        
        :param state: state object representing current track
        """
        if (not self.is_valid_mode()) or (not self.screen_title.active): return

        self.set_current_track_index(state)
        left = self.current_track_index
        right = 0

        if self.audio_files and len(self.audio_files) > 1:
            right = len(self.audio_files) - self.current_track_index - 1

        self.left_button.change_label(str(left))
        self.right_button.change_label(str(right))

    def set_current_track_index(self, state):
        """ Set current track index
        
        :param state: state object representing current track
        """
        if not self.is_valid_mode(): return

        if self.config[CURRENT][MODE] == CD_PLAYER and getattr(
                state, "cd_track_id", None):
            self.config[CD_PLAYBACK][CD_TRACK] = state["cd_track_id"]

        self.current_track_index = 0

        if self.playlist_size == 1:
            return

        if not self.audio_files:
            self.audio_files = self.get_audio_files()
            if not self.audio_files: return

        i = self.get_current_track_index(state)
        self.current_track_index = i

    def create_left_panel(self, layout, listeners):
        """ Create left side buttons panel
        
        :param layout: panel layout 
        :param listeners: button listeners 
        """
        panel_layout = BorderLayout(layout.LEFT)
        panel_layout.set_percent_constraints(PERCENT_SIDE_BOTTOM_HEIGHT,
                                             PERCENT_SIDE_BOTTOM_HEIGHT, 0, 0)
        self.left_button = self.factory.create_left_button(
            panel_layout.CENTER, '', 40, 100)
        self.shutdown_button = self.factory.create_shutdown_button(
            panel_layout.TOP)
        self.home_button = self.factory.create_button(KEY_HOME,
                                                      KEY_HOME,
                                                      panel_layout.BOTTOM,
                                                      image_size_percent=36)
        panel = Container(self.util, layout.LEFT)
        panel.add_component(self.shutdown_button)
        panel.add_component(self.left_button)
        panel.add_component(self.home_button)
        Container.add_component(self, panel)

    def create_right_panel(self, layout, listeners):
        """ Create right side buttons panel
        
        :param layout: panel layout 
        :param listeners: button listeners 
        """
        panel_layout = BorderLayout(layout.RIGHT)
        panel_layout.set_percent_constraints(PERCENT_SIDE_BOTTOM_HEIGHT,
                                             PERCENT_SIDE_BOTTOM_HEIGHT, 0, 0)
        self.play_button = self.factory.create_play_pause_button(
            panel_layout.TOP, listeners[KEY_PLAY_PAUSE])
        self.right_button = self.factory.create_right_button(
            panel_layout.CENTER, '', 40, 100)
        self.time_volume_button = self.factory.create_time_volume_button(
            panel_layout.BOTTOM, self.toggle_time_volume)
        panel = Container(self.util, layout.RIGHT)
        panel.add_component(self.play_button)
        panel.add_component(self.right_button)
        panel.add_component(self.time_volume_button)
        Container.add_component(self, panel)

    def toggle_time_volume(self):
        """ Switch between time and volume controls """

        if self.volume_visible:
            self.volume.set_visible(False)
            self.time_control.set_visible(True)
            self.volume_visible = False
        else:
            volume_level = int(self.config[PLAYER_SETTINGS][VOLUME])
            self.volume.set_position(volume_level)
            self.volume.update_position()
            self.volume.set_visible(True)
            self.time_control.set_visible(False)
            self.volume_visible = True
        self.clean_draw_update()

    def eject_cd(self, state):
        """ Eject CD
        
        :param state: button state object
        """
        self.audio_files = []
        self.screen_title.set_text(" ")
        self.update_arrow_button_labels(state)
        self.time_control.reset()
        self.cd_album = None
        self.set_cd_album_art_image()

    def set_current(self, new_track=False, state=None):
        """ Set current file or playlist
        
        :param new_track: True - new audio file
        """
        self.cd_album = getattr(state, "album", None)

        if self.config[CURRENT][MODE] == AUDIO_FILES:
            state.full_screen_image = self.set_audio_file_image()
        elif self.config[CURRENT][MODE] == CD_PLAYER and getattr(
                state, "source", None) != INIT:
            state.full_screen_image = self.set_cd_album_art_image()
            state.image_base = self.file_button.components[1].content

        config_volume_level = int(self.config[PLAYER_SETTINGS][VOLUME])
        if state:
            state.volume = config_volume_level

        self.set_audio_file(new_track, state)

        if self.volume.get_position() != config_volume_level:
            self.volume.set_position(config_volume_level)
            self.volume.update_position()

    def set_audio_file_image(self):
        """ Set audio file image """

        f = self.config[FILE_PLAYBACK][CURRENT_FOLDER]
        if not f: return None

        img_tuple = self.util.get_audio_file_icon(f, self.bounding_box)
        self.set_file_button(img_tuple)

        return img_tuple[1]

    def set_cd_album_art_image(self):
        """ Set CD album art image """

        img_tuple = self.util.get_cd_album_art(self.cd_album,
                                               self.bounding_box)
        if img_tuple == None:
            return None
        self.set_file_button(img_tuple)
        self.file_button.clean_draw_update()

        return img_tuple[1]

    def set_file_button(self, img_tuple):
        """ Set image in file button
        
        :param img_tuple: tuple where first element is image location, second element image itself 
        """
        full_screen_image = img_tuple[1]
        self.file_button.state.full_screen_image = full_screen_image

        scale_ratio = self.util.get_scale_ratio(
            (self.layout.CENTER.w, self.layout.CENTER.h), full_screen_image)
        img = self.util.scale_image(full_screen_image, scale_ratio)

        self.file_button.components[1].content = img
        self.file_button.state.icon_base = img
        self.file_button.components[
            1].image_filename = self.file_button.state.image_filename = img_tuple[
                0]

        self.file_button.components[1].content_x = self.layout.CENTER.x + (
            self.layout.CENTER.w - img.get_size()[0]) / 2

        if self.layout.CENTER.h > img.get_size()[1]:
            self.file_button.components[
                1].content_y = self.layout.CENTER.y + int(
                    (self.layout.CENTER.h - img.get_size()[1]) / 2) + 1
        else:
            self.file_button.components[1].content_y = self.layout.CENTER.y

    def set_audio_file(self, new_track, s=None):
        """ Set new audio file
        
        :param new_track: True - new audio file
        "param s" button state object
        """
        state = State()

        if s:
            state.playback_mode = getattr(s, "playback_mode", FILE_AUDIO)
            state.playlist_track_number = getattr(s, "playlist_track_number",
                                                  None)
            if self.config[CURRENT][MODE] == CD_PLAYER and getattr(
                    s, "source", None) != INIT:
                image_base = getattr(s, "image_base", None)
                if image_base != None:
                    state.image_base = image_base
        else:
            m = self.config[FILE_PLAYBACK][CURRENT_FILE_PLAYBACK_MODE]
            if m:
                state.playback_mode = m
            else:
                state.playback_mode = FILE_AUDIO

        if self.config[CURRENT][MODE] == AUDIO_FILES:
            self.current_folder = self.config[FILE_PLAYBACK][CURRENT_FOLDER]
            if not self.current_folder:
                return
            state.folder = self.current_folder
            state.file_name = self.config[FILE_PLAYBACK][CURRENT_FILE]
            if state.folder[-1] == os.sep:
                state.folder = state.folder[:-1]

            if os.sep in state.file_name:
                state.url = "\"" + state.file_name + "\""
            else:
                state.url = "\"" + state.folder + os.sep + state.file_name + "\""

            state.music_folder = self.config[AUDIO][MUSIC_FOLDER]
        elif self.config[CURRENT][MODE] == CD_PLAYER:
            state.file_name = s.file_name
            state.url = getattr(s, "url", s.file_name)
            parts = s.file_name.split()
            self.config[CD_PLAYBACK][CD_DRIVE_NAME] = parts[0][len("cdda:///"
                                                                   ):]
            id = self.cdutil.get_cd_drive_id_by_name(
                self.config[CD_PLAYBACK][CD_DRIVE_NAME])
            self.config[CD_PLAYBACK][CD_DRIVE_ID] = int(id)
            self.config[CD_PLAYBACK][CD_TRACK] = int(parts[1].split("=")[1])

        state.mute = self.config[PLAYER_SETTINGS][MUTE]
        state.pause = self.config[PLAYER_SETTINGS][PAUSE]
        state.file_type = FILE_AUDIO
        state.dont_notify = True
        state.source = FILE_AUDIO

        if self.config[FILE_PLAYBACK][
                CURRENT_FILE_PLAYBACK_MODE] == FILE_AUDIO or self.config[
                    CURRENT][MODE] == CD_PLAYER:
            self.audio_files = self.get_audio_files()
        elif self.config[FILE_PLAYBACK][
                CURRENT_FILE_PLAYBACK_MODE] == FILE_PLAYLIST:
            state.file_name = self.config[FILE_PLAYBACK][CURRENT_FILE_PLAYLIST]
            self.load_playlist(state)
            state.file_name = self.config[FILE_PLAYBACK][CURRENT_FILE]
            self.audio_files = self.get_audio_files_from_playlist()
            state.playback_mode = FILE_PLAYLIST
            n = getattr(s, "file_name", None)
            if n:
                state.file_name = n

            try:
                state.playlist_track_number = int(state.file_name) - 1
            except:
                state.playlist_track_number = self.get_current_track_index(
                    state)

        source = None
        if s:
            source = getattr(s, "source", None)

        if new_track:
            tt = 0.0
        else:
            if self.config[CURRENT][MODE] == CD_PLAYER:
                tt = self.config[CD_PLAYBACK][CD_TRACK_TIME]
            else:
                tt = self.config[FILE_PLAYBACK][CURRENT_TRACK_TIME]

        if (isinstance(tt, str) and len(tt) != 0) or (
                isinstance(tt, float) or
            (source and source == RESUME)) or isinstance(tt, int):
            state.track_time = tt

        self.time_control.slider.set_position(0)

        if self.file_button and self.file_button.components[
                1] and self.file_button.components[1].content:
            state.icon_base = self.file_button.components[1].content

        if s and s.volume:
            state.volume = s.volume

        if self.config[CURRENT][MODE] == CD_PLAYER and s and getattr(
                s, "source", None) == INIT:
            try:
                self.cd_album = self.util.cd_titles[self.config[CD_PLAYBACK]
                                                    [CD_DRIVE_NAME]]
                self.set_cd_album_art_image()
                state.image_base = self.file_button.components[1].content
            except:
                self.cd_album = None

        if getattr(s, "full_screen_image", None) != None:
            state.full_screen_image = s.full_screen_image

        self.notify_play_listeners(state)

    def get_audio_files_from_playlist(self):
        """ Call player for files in the playlist 
        
        :return: list of files from playlist
        """
        playlist = self.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 = playlist[n]
                files.append(st)
        return files

    def restore_current_folder(self, state=None):
        """ Set current folder in config object
        
        :param state: not used
        """
        self.config[FILE_PLAYBACK][CURRENT_FOLDER] = self.current_folder

    def set_audio_file_playlist(self, index):
        """ Set file in playlist
        
        :param index: file index in playlist
        """
        state = State()
        state.playback_mode = FILE_PLAYLIST
        state.playlist_track_number = index
        state.file_type = FILE_AUDIO
        self.current_folder = self.config[FILE_PLAYBACK][CURRENT_FOLDER]
        self.notify_play_listeners(state)

    def go_back(self):
        """ Go back """

        if self.config[CURRENT][MODE] == CD_PLAYER:
            return

        img_tuple = self.util.get_audio_file_icon(self.current_folder,
                                                  self.layout.CENTER)
        img = img_tuple[1]
        self.file_button.components[1].content = img
        self.file_button.state.icon_base = img_tuple

        self.file_button.components[1].content_x = self.layout.CENTER.x
        if self.layout.CENTER.h > img.get_size()[1]:
            self.file_button.components[
                1].content_y = self.layout.CENTER.y + int(
                    (self.layout.CENTER.h - img.get_size()[1]) / 2)
        else:
            self.file_button.components[1].content_y = self.layout.CENTER.y

    def recursive_change_folder(self):
        start_folder = self.config[FILE_PLAYBACK][CURRENT_FILE_PLAYLIST]
        current_folder = self.config[FILE_PLAYBACK][CURRENT_FOLDER]
        f = self.util.file_util.get_next_folder_with_audio_files(
            start_folder, current_folder)
        if f == None or (f != None and f[0] == None):
            self.config[FILE_PLAYBACK][CURRENT_FILE_PLAYBACK_MODE] = FILE_AUDIO
            self.config[FILE_PLAYBACK][CURRENT_FILE_PLAYLIST] = None
            return False

        self.config[FILE_PLAYBACK][CURRENT_FOLDER] = f[0]
        self.config[FILE_PLAYBACK][CURRENT_FILE] = f[1]
        self.config[FILE_PLAYBACK][CURRENT_TRACK_TIME] = None
        state = State()
        state.file_type = FOLDER
        state.url = f[0]
        state.long_press = True
        state.playback_mode = FILE_RECURSIVE
        self.current_track_index = 0
        state.dont_notify = True
        self.audio_files = self.get_audio_files()
        self.recursive_notifier(f[0])
        return True

    def end_of_track(self):
        """ Handle end of track """

        if not self.screen_title.active:
            return

        i = getattr(self, "current_track_index", None)
        if i == None: return
        self.stop_timer()
        mode = self.config[CURRENT][MODE]
        if mode == RADIO or mode == STREAM or not self.audio_files:
            return

        self.time_control.stop_thread()

        if self.config[AUTO_PLAY_NEXT_TRACK]:
            if self.current_track_index == len(self.audio_files) - 1:
                if self.config[FILE_PLAYBACK][
                        CURRENT_FILE_PLAYBACK_MODE] == FILE_RECURSIVE:
                    if not self.recursive_change_folder():
                        self.stop_recursive_playback()
                        return
                elif self.config[CYCLIC_PLAYBACK]:
                    self.current_track_index = 0
            else:
                self.current_track_index += 1

            if mode == AUDIO_FILES:
                self.config[FILE_PLAYBACK][CURRENT_TRACK_TIME] = None
            elif mode == AUDIOBOOKS:
                self.config[AUDIOBOOKS][BROWSER_BOOK_TIME] = None

            self.change_track(self.current_track_index)

            if self.config[FILE_PLAYBACK][
                    CURRENT_FILE_PLAYBACK_MODE] == FILE_RECURSIVE:
                self.file_button.clean_draw_update()

    def set_playlist_size(self, size):
        """ Set playlist size
        
        :param size: playlist size
        """
        self.playlist_size = size
        self.stop_timer()

    def set_visible(self, flag):
        """ Set visibility flag
         
        :param flag: True - screen visible, False - screen invisible
        """
        Container.set_visible(self, flag)

        if flag:
            if self.volume_visible:
                self.volume.set_visible(True)
                self.time_control.set_visible(False)
            else:
                self.volume.set_visible(False)
                self.time_control.set_visible(True)

    def add_play_listener(self, listener):
        """ Add play listener
        
        :param listener: event listener
        """
        if listener not in self.play_listeners:
            self.play_listeners.append(listener)

    def notify_play_listeners(self, state):
        """ Notify all play listeners
        
        :param state: button state
        """
        if not self.screen_title.active:
            return

        m = getattr(state, "playback_mode", None)
        if m != None and m != FILE_PLAYLIST:
            state.icon_base = self.file_button.state.icon_base
        folder = getattr(state, "folder", None)
        if folder:
            state.cover_art_folder = self.util.file_util.get_cover_art_folder(
                state.folder)

        for listener in self.play_listeners:
            listener(state)

    def enable_player_screen(self, flag):
        """ Enable player screen
        
        :param flag: enable/disable flag
        """
        self.screen_title.active = flag
        self.time_control.active = flag

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

        self.add_button_observers(self.shutdown_button,
                                  update_observer,
                                  redraw_observer=None)
        self.shutdown_button.add_cancel_listener(redraw_observer)
        self.screen_title.add_listener(redraw_observer)

        self.add_button_observers(self.play_button,
                                  update_observer,
                                  redraw_observer=None)
        self.add_button_observers(self.home_button, update_observer,
                                  redraw_observer)

        self.add_button_observers(self.left_button,
                                  update_observer,
                                  redraw_observer=None)
        self.left_button.add_label_listener(update_observer)
        self.add_button_observers(self.right_button,
                                  update_observer,
                                  redraw_observer=None)
        self.right_button.add_label_listener(update_observer)

        self.volume.add_slide_listener(update_observer)
        self.volume.add_knob_listener(update_observer)
        self.volume.add_press_listener(update_observer)
        self.volume.add_motion_listener(update_observer)

        self.add_button_observers(self.time_volume_button,
                                  update_observer,
                                  redraw_observer,
                                  release=False)
        self.add_button_observers(self.file_button,
                                  update_observer,
                                  redraw_observer,
                                  press=False,
                                  release=False)

        self.time_control.web_seek_listener = update_observer
        self.time_control.add_start_timer_listener(start_time_control)
        self.time_control.add_stop_timer_listener(stop_time_control)
        self.time_control.slider.add_slide_listener(update_observer)
        self.time_control.slider.add_knob_listener(update_observer)
        self.time_control.slider.add_press_listener(update_observer)
        self.time_control.slider.add_motion_listener(update_observer)
예제 #9
0
class CollectionListNavigator(Container):
    """ Collection List navigator menu """

    def __init__(self, util, bounding_box, listeners, collection_mode=GENRE):
        """ Initializer

        :param util: utility object
        :param bounding_box: bounding box
        :param listeners: buttons listeners
        """
        Container.__init__(self, util)
        self.factory = Factory(util)
        self.name = "collectionlist.navigator"
        self.content = bounding_box
        self.content_x = bounding_box.x
        self.content_y = bounding_box.y
        self.listeners = listeners
        self.menu_buttons = []
        self.config = util.config
        self.use_web = self.config[USAGE][USE_WEB]
        self.go_keyboard = listeners[KEY_KEYBOARD_KEY]
        self.keyboard_callback = listeners[KEY_CALLBACK]
        self.go_abc = listeners[KEY_ABC]

        self.bgr = util.config[COLORS][COLOR_DARK_LIGHT]

        self.arrow_layout = BorderLayout(bounding_box)
        self.arrow_layout.set_percent_constraints(0, 0, PERCENT_ARROW_WIDTH, PERCENT_ARROW_WIDTH)

        self.collection_mode = collection_mode
        self.update_observer = None
        self.redraw_observer = None

        self.set_buttons(collection_mode)

    def set_buttons(self, collection_mode):
        """ Set navigator buttons

        :param collection_mode: mode
        """
        if self.menu_buttons and collection_mode in TEXT_MODES and self.collection_mode in TEXT_MODES:
            self.collection_mode = collection_mode
            return 

        self.collection_mode = collection_mode
        self.components = []
        self.menu_buttons = []

        constr = self.arrow_layout.LEFT
        self.left_button = self.factory.create_page_down_button(constr, "0", 40, 100)
        self.left_button.add_release_listener(self.listeners[GO_LEFT_PAGE])
        self.add_component(self.left_button)
        self.menu_buttons.append(self.left_button)

        constr = self.arrow_layout.RIGHT
        self.right_button = self.factory.create_page_up_button(constr, "0", 40, 100)
        self.right_button.add_release_listener(self.listeners[GO_RIGHT_PAGE])
        self.add_component(self.right_button)
        self.menu_buttons.append(self.right_button)

        if collection_mode in TEXT_MODES:
            n = 6
        elif collection_mode == TYPE:
            n = 4
        else:
            n = 5
        layout = GridLayout(self.arrow_layout.CENTER)
        layout.set_pixel_constraints(1, n, 1, 0)
        layout.current_constraints = 0

        self.add_button(KEY_HOME, KEY_HOME, layout, self.listeners[KEY_HOME])
        self.add_button(KEY_BACK, KEY_BACK, layout, self.listeners[KEY_BACK])
        self.add_button(COLLECTION, KEY_BACK, layout, self.listeners[COLLECTION])

        if n == 6:
            self.add_button(IMAGE_ABC, KEY_HOME, layout, self.pre_abc)
        if n != 4:
            self.add_button(IMAGE_BOOK_GENRE, KEY_HOME, layout, self.pre_keyboard)
        self.add_button(KEY_PLAYER, KEY_PLAY_PAUSE, layout, self.listeners[KEY_PLAYER])

        if self.use_web and self.update_observer != None:
            self.add_observers(self.update_observer, self.redraw_observer)

    def add_button(self, img_name, key, layout, listener):
        """ Add button

        :param img_name: button image name
        :param key: keyboard key
        :param layout: button layout
        :param listener: button listener
        """
        c = layout.get_next_constraints()
        b = self.factory.create_button(img_name, key, c, listener, self.bgr, image_size_percent=IMAGE_SIZE_PERCENT)
        self.add_component(b)
        self.menu_buttons.append(b)

    def pre_abc(self, state=None):
        """ Called before openning ABC screen

        :param state: button state
        """
        state.title = self.config[LABELS][self.collection_mode]
        state.visibility = False
        state.callback = self.keyboard_callback
        self.go_abc(state)

    def pre_keyboard(self, state=None):
        """ Called before openning keyboard screen

        :param state: button state
        """
        state.title = self.config[LABELS][self.collection_mode]
        state.visibility = False
        state.callback = self.keyboard_callback
        self.go_keyboard(state)

    def add_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
        """
        if self.update_observer == None:
            self.update_observer = update_observer
            self.redraw_observer = redraw_observer

        for b in self.menu_buttons:
            self.add_button_observers(b, update_observer, redraw_observer)
예제 #10
0
    def __init__(self, util, bounding_box, listeners, bgr):
        """ Initializer
        
        :param util: utility object
        :param bounding_box: bounding box
        :param listeners: buttons listeners
        :param bgr: menu background        
        """ 
        Container.__init__(self, util)
        self.factory = Factory(util)
        self.name = "navigator"
        self.content = bounding_box
        self.content_x = bounding_box.x
        self.content_y = bounding_box.y
        self.menu_buttons = []

        arrow_layout = BorderLayout(bounding_box)
        arrow_layout.set_percent_constraints(0, 0, PERCENT_ARROW_WIDTH, PERCENT_ARROW_WIDTH)
        
        constr = arrow_layout.LEFT
        self.left_button = self.factory.create_page_down_button(constr, "0", 40, 100)
        self.left_button.add_release_listener(listeners[GO_LEFT_PAGE])
        self.add_component(self.left_button)
        self.menu_buttons.append(self.left_button)
        
        constr = arrow_layout.RIGHT
        self.right_button = self.factory.create_page_up_button(constr, "0", 40, 100)
        self.right_button.add_release_listener(listeners[GO_RIGHT_PAGE])
        self.add_component(self.right_button)
        self.menu_buttons.append(self.right_button)
        
        layout = GridLayout(arrow_layout.CENTER)
        layout.set_pixel_constraints(1, 5, 1, 0)        
        layout.current_constraints = 0
        image_size = 64 
        
        constr = layout.get_next_constraints()
        self.home_button = self.factory.create_button(KEY_HOME, KEY_HOME, constr, listeners[KEY_HOME], bgr, image_size_percent=image_size)
        self.add_component(self.home_button)
        self.menu_buttons.append(self.home_button)
        
        constr = layout.get_next_constraints()
        self.user_home_button = self.factory.create_button(KEY_USER_HOME, KEY_MENU, constr, listeners[GO_USER_HOME], bgr, image_size_percent=image_size)
        self.add_component(self.user_home_button)
        self.menu_buttons.append(self.user_home_button)
        
        constr = layout.get_next_constraints()
        self.root_button = self.factory.create_button(KEY_ROOT, KEY_ROOT, constr, listeners[GO_ROOT], bgr, image_size_percent=image_size)
        self.add_component(self.root_button)
        self.menu_buttons.append(self.root_button)

        constr = layout.get_next_constraints()
        self.parent_button = self.factory.create_button(KEY_PARENT, KEY_PARENT, constr, listeners[GO_TO_PARENT], bgr, image_size_percent=image_size)
        self.add_component(self.parent_button)
        self.menu_buttons.append(self.parent_button)

        constr = layout.get_next_constraints()
        self.back_button = self.factory.create_button(KEY_BACK, KEY_BACK, constr, None, bgr, image_size_percent=image_size)
        self.back_button.add_release_listener(listeners[GO_BACK])
        self.back_button.add_release_listener(listeners[KEY_PLAY_FILE])
        self.add_component(self.back_button)
        self.menu_buttons.append(self.back_button)
예제 #11
0
    def __init__(self, util, bounding_box, listeners, bgr, pages):
        """ Initializer
        
        :param util: utility object
        :param bounding_box: bounding box
        :param listeners: buttons listeners
        :param bgr: menu background        
        """
        Container.__init__(self, util)
        self.factory = Factory(util)
        self.name = "navigator"
        self.content = bounding_box
        self.content_x = bounding_box.x
        self.content_y = bounding_box.y
        self.menu_buttons = []

        arrow_layout = BorderLayout(bounding_box)
        arrow_layout.set_percent_constraints(0, 0, PERCENT_ARROW_WIDTH,
                                             PERCENT_ARROW_WIDTH)

        if pages > 1:
            constr = arrow_layout.LEFT
            self.left_button = self.factory.create_page_down_button(
                constr, "0", 40, 100)
            self.left_button.add_release_listener(listeners[GO_LEFT_PAGE])
            self.add_component(self.left_button)
            self.menu_buttons.append(self.left_button)

            constr = arrow_layout.RIGHT
            self.right_button = self.factory.create_page_up_button(
                constr, "0", 40, 100)
            self.right_button.add_release_listener(listeners[GO_RIGHT_PAGE])
            self.add_component(self.right_button)
            self.menu_buttons.append(self.right_button)

        if pages > 1:
            layout = GridLayout(arrow_layout.CENTER)
        else:
            layout = GridLayout(bounding_box)

        layout.set_pixel_constraints(1, 3, 1, 0)
        layout.current_constraints = 0
        image_size = 64

        constr = layout.get_next_constraints()
        self.home_button = self.factory.create_button(
            KEY_HOME,
            KEY_HOME,
            constr,
            listeners[KEY_HOME],
            bgr,
            image_size_percent=image_size)
        self.add_component(self.home_button)
        self.menu_buttons.append(self.home_button)

        constr = layout.get_next_constraints()
        self.favorites_button = self.factory.create_button(
            KEY_FAVORITES,
            KEY_SETUP,
            constr,
            listeners[KEY_FAVORITES],
            bgr,
            image_size_percent=image_size)
        self.add_component(self.favorites_button)
        self.menu_buttons.append(self.favorites_button)

        constr = layout.get_next_constraints()
        self.player_button = self.factory.create_button(
            KEY_PLAYER,
            KEY_PLAY_PAUSE,
            constr,
            listeners[KEY_PLAYER],
            bgr,
            image_size_percent=image_size)
        self.add_component(self.player_button)
        self.menu_buttons.append(self.player_button)
예제 #12
0
파일: network.py 프로젝트: thekismet/Peppy
    def __init__(self, util, listeners, voice_assistant):
        """ Initializer

        :param util: utility object
        :param listeners: listeners
        :param voice_assistant: voice assistant
        """
        self.util = util
        self.config = util.config
        self.factory = Factory(util)
        self.check_internet_connectivity = listeners[KEY_CHECK_INTERNET]
        self.go_home = listeners[KEY_HOME]
        self.set_modes = listeners[KEY_SET_MODES]
        self.linux = self.config[LINUX_PLATFORM]

        self.wifi_util = WiFiUtil(util)
        self.bluetooth_util = self.util.get_bluetooth_util()

        self.bounding_box = util.screen_rect
        layout = BorderLayout(self.bounding_box)
        layout.set_percent_constraints(PERCENT_TOP_HEIGHT, PERCENT_BOTTOM_HEIGHT, 0, 0)

        if self.linux and self.config[USAGE][USE_BLUETOOTH]:
            rows = 7
        else:
            rows = 6

        columns = 1
        d = [rows, columns]
        MenuScreen.__init__(self, util, listeners, rows, columns, voice_assistant, d, None, page_in_title=False, show_loading=False)
        self.title = self.config[LABELS]["network"]
        self.set_title(1)

        center_layout = BorderLayout(self.menu_layout)
        center_layout.set_percent_constraints(0, 0, 47, 0)

        left_layout = center_layout.LEFT
        right_layout = center_layout.CENTER

        label_layout = GridLayout(left_layout)
        label_layout.set_pixel_constraints(rows, columns)
        label_layout.get_next_constraints()

        value_layout = GridLayout(right_layout)
        value_layout.set_pixel_constraints(rows, columns)
        value_layout.get_next_constraints()

        self.network_panel = Container(util, self.menu_layout)

        rect = pygame.Rect(self.menu_layout.x, self.menu_layout.y + 1, self.menu_layout.w, self.menu_layout.h - 1)
        b = util.config[BACKGROUND][MENU_BGR_COLOR]
        bgr = Component(util, rect, 0, 0, self.menu_layout, bgr=b)
        bgr.name = "network.panel.bgr"
        self.network_panel.add_component(bgr)

        self.internet_label = self.add_label(label_layout, self.network_panel, 1)
        self.ethernet_label = self.add_label(label_layout, self.network_panel, 2)
        self.wifi_network_label = self.add_label(label_layout, self.network_panel, 3)
        self.wifi_ip_label = self.add_label(label_layout, self.network_panel, 4)
        if self.linux and self.config[USAGE][USE_BLUETOOTH]:
            self.bluetooth_label = self.add_label(label_layout, self.network_panel, 5)

        self.internet = self.add_value(value_layout, self.network_panel, 1)
        self.ethernet_ip = self.add_value(value_layout, self.network_panel, 2)
        self.wifi_network = self.add_value(value_layout, self.network_panel, 3)
        self.wifi_ip = self.add_value(value_layout, self.network_panel, 4)
        if self.linux and self.config[USAGE][USE_BLUETOOTH]:
            self.bluetooth = self.add_value(value_layout, self.network_panel, 5)

        self.add_component(self.network_panel)

        listeners[KEY_REFRESH] = self.set_current
        listeners[KEY_DISCONNECT] = self.disconnect_wifi
        listeners[KEY_BLUETOOTH_REMOVE] = self.remove_bluetooth_devices

        self.navigator = NetworkNavigator(self.util, self.layout.BOTTOM, listeners)
        self.add_component(self.navigator)
        self.original_networks = None
        self.networks = None
        self.current_network = None
        self.current_wifi_network = None
        self.clicked = False
예제 #13
0
    def __init__(self, util, bounding_box, listeners, language_url=None):
        """ Initializer
        
        :param util: utility object
        :param bounding_box: bounding box
        :param listeners: buttons listeners
        :param language_url: language constant        
        """
        Container.__init__(self, util)
        self.factory = Factory(util)
        self.name = "navigator"
        arrow_layout = BorderLayout(bounding_box)
        arrow_layout.set_percent_constraints(0, 0, PERCENT_ARROW_WIDTH,
                                             PERCENT_ARROW_WIDTH)
        self.menu_buttons = []

        constr = arrow_layout.LEFT
        self.left_button = self.factory.create_page_down_button(
            constr, "0", 34, 100)
        self.left_button.add_release_listener(listeners[GO_LEFT_PAGE])
        self.add_component(self.left_button)
        self.menu_buttons.append(self.left_button)

        constr = arrow_layout.RIGHT
        self.right_button = self.factory.create_page_up_button(
            constr, "0", 34, 100)
        self.right_button.add_release_listener(listeners[GO_RIGHT_PAGE])
        self.add_component(self.right_button)
        self.menu_buttons.append(self.right_button)

        layout = GridLayout(arrow_layout.CENTER)
        if language_url == "":  # English-USA
            buttons = 5
        elif language_url == None:  #Russian
            buttons = 6
        else:
            buttons = 4
        layout.set_pixel_constraints(1, buttons, 1, 0)
        layout.current_constraints = 0
        image_size = 56
        b = util.config[BACKGROUND][FOOTER_BGR_COLOR]

        constr = layout.get_next_constraints()
        self.home_button = self.factory.create_button(
            KEY_HOME,
            KEY_HOME,
            constr,
            listeners[KEY_HOME],
            b,
            image_size_percent=image_size)
        self.add_component(self.home_button)
        self.menu_buttons.append(self.home_button)

        if language_url == None:
            constr = layout.get_next_constraints()
            self.abc_button = self.factory.create_button(
                IMAGE_ABC,
                KEY_SETUP,
                constr,
                listeners[GO_USER_HOME],
                b,
                image_size_percent=image_size)
            self.add_component(self.abc_button)
            self.menu_buttons.append(self.abc_button)

        constr = layout.get_next_constraints()
        self.new_books_button = self.factory.create_button(
            IMAGE_NEW_BOOKS,
            KEY_MENU,
            constr,
            listeners[GO_ROOT],
            b,
            image_size_percent=image_size)
        self.add_component(self.new_books_button)
        self.menu_buttons.append(self.new_books_button)

        if language_url == None or language_url == "":  # English-USA or Russian
            constr = layout.get_next_constraints()
            self.genre_button = self.factory.create_button(
                IMAGE_BOOK_GENRE,
                KEY_ROOT,
                constr,
                listeners[GO_TO_PARENT],
                b,
                image_size_percent=image_size)
            self.add_component(self.genre_button)
            self.menu_buttons.append(self.genre_button)

        constr = layout.get_next_constraints()
        self.player_button = self.factory.create_button(
            IMAGE_PLAYER,
            KEY_PLAY_PAUSE,
            constr,
            listeners[GO_PLAYER],
            b,
            source=BOOK_NAVIGATOR,
            image_size_percent=image_size)
        self.add_component(self.player_button)
        self.menu_buttons.append(self.player_button)

        constr = layout.get_next_constraints()
        self.back_button = self.factory.create_button(
            KEY_BACK,
            KEY_BACK,
            constr,
            None,
            b,
            source=BOOK_NAVIGATOR_BACK,
            image_size_percent=image_size)
        self.back_button.add_release_listener(listeners[GO_BACK])
        try:
            self.back_button.add_release_listener(listeners[KEY_PLAY_FILE])
        except:
            pass
        self.add_component(self.back_button)
        self.menu_buttons.append(self.back_button)
예제 #14
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 = 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

        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,
                                  self.config[ALIGN_BUTTON_CONTENT_X])

        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
예제 #15
0
    def __init__(self, util, bounding_box, name, items, arrow_items=None):
        """ Initializer
        
        :param util: utility object
        :param bounding_box: bounding box
        :param name: navigator name
        :param items: dictionary with button details
        :param arrow_items: dictionary with arrow buttons details
        """
        Container.__init__(self, util)
        self.factory = Factory(util)
        self.name = name
        self.content = bounding_box
        self.content_x = bounding_box.x
        self.content_y = bounding_box.y
        self.buttons = []

        if arrow_items:
            arrow_layout = BorderLayout(bounding_box)
            left_arrow = arrow_items[0]
            listeners = left_arrow[LISTENER]
            arrow_layout.set_percent_constraints(0, 0, PERCENT_ARROW_WIDTH,
                                                 PERCENT_ARROW_WIDTH)
            constr = arrow_layout.LEFT
            button = self.factory.create_page_down_button(constr, "0", 40, 100)
            button.add_release_listener(listeners[0])
            self.add_component(button)
            self.buttons.append(button)
            layout = GridLayout(arrow_layout.CENTER)
        else:
            layout = GridLayout(bounding_box)

        layout.set_pixel_constraints(1, len(items), 1, 0)
        layout.current_constraints = 0
        image_size = 64
        b = util.config[BACKGROUND][FOOTER_BGR_COLOR]

        for item in items:
            constr = layout.get_next_constraints()
            image_name = item[IMAGE_NAME]
            listeners = item[LISTENER]
            keybiard_key = item[KEYBOARD_KEY]
            source = item[SOURCE]

            if len(listeners) == 1:
                button = self.factory.create_button(
                    image_name,
                    keybiard_key,
                    constr,
                    listeners[0],
                    b,
                    image_size_percent=image_size,
                    source=source)
            else:
                button = self.factory.create_button(
                    image_name,
                    keybiard_key,
                    constr,
                    None,
                    b,
                    image_size_percent=image_size,
                    source=source)
                for listener in listeners:
                    button.add_release_listener(listener)

            self.add_component(button)
            self.buttons.append(button)

        if arrow_items:
            right_arrow = arrow_items[1]
            listeners = right_arrow[LISTENER]
            constr = arrow_layout.RIGHT
            button = self.factory.create_page_up_button(constr, "0", 40, 100)
            button.add_release_listener(listeners[0])
            self.add_component(button)
            self.buttons.append(button)
예제 #16
0
class CdTracksScreen(Screen):
    """ File Browser Screen """
    def __init__(self, util, listeners, voice_assistant, state):
        """ Initializer
        
        :param util: utility object
        :param listeners: file browser listeners
        """
        self.util = util
        self.config = util.config
        self.cdutil = CdUtil(util)
        self.factory = Factory(util)
        self.bounding_box = util.screen_rect
        self.layout = BorderLayout(self.bounding_box)
        self.layout.set_percent_constraints(PERCENT_TOP_HEIGHT,
                                            PERCENT_BOTTOM_HEIGHT, 0, 0)
        Screen.__init__(self, util, "", PERCENT_TOP_HEIGHT, voice_assistant,
                        "cd_tracks_screen_title", True, self.layout.TOP)
        color_dark_light = self.config[COLORS][COLOR_DARK_LIGHT]
        self.current_cd_drive_name = self.config[CD_PLAYBACK][CD_DRIVE_NAME]
        self.current_cd_drive_id = self.config[CD_PLAYBACK][CD_DRIVE_ID]

        self.filelist = self.get_filelist()

        self.file_menu = FileMenu(self.filelist,
                                  util,
                                  None, (0, 0, 0),
                                  self.layout.CENTER,
                                  align=ALIGN_LEFT)

        self.go_cd_player = listeners[KEY_PLAYER]
        self.file_menu.add_play_file_listener(self.play_track)
        Container.add_component(self, self.file_menu)

        listeners[GO_LEFT_PAGE] = self.file_menu.page_down
        listeners[GO_RIGHT_PAGE] = self.file_menu.page_up
        listeners[KEY_EJECT] = self.eject_cd
        listeners[KEY_REFRESH] = self.refresh_tracks
        connected_cd_drives = self.cdutil.get_cd_drives_number()
        self.navigator = CdTracksNavigator(util, connected_cd_drives,
                                           self.layout.BOTTOM, listeners,
                                           color_dark_light)
        Container.add_component(self, self.navigator)

        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)
        self.file_menu.update_buttons()
        self.page_turned = False
        self.animated_title = True

    def play_track(self, state):
        """ Set config and go to player
        
        :param state: state object with track info
        """
        self.config[CD_PLAYBACK][CD_DRIVE_ID] = self.current_cd_drive_id
        self.config[CD_PLAYBACK][CD_DRIVE_NAME] = self.current_cd_drive_name
        self.config[CD_PLAYBACK][CD_TRACK_TIME] = "0"

        if self.current_cd_drive_name != self.screen_title.text:
            state.album = self.screen_title.text

        self.go_cd_player(state)

    def get_filelist(self):
        """ Return CD tracks
        
        :return: page with CD tracks
        """
        rows = 5
        columns = 2

        layout = GridLayout(self.layout.CENTER)
        layout.set_pixel_constraints(rows, columns, 1, 1)
        constr = layout.get_next_constraints()
        fixed_height = int((constr.h * 35) / 100.0)

        tracks = self.cdutil.get_cd_tracks(rows, columns, fixed_height,
                                           self.current_cd_drive_name)
        if tracks == None:
            tracks = []
        return Page(tracks, rows, columns)

    def set_current(self, state):
        """ Set current CD drive
        
        :param state: state object with drive info
        """
        if not self.current_cd_drive_name or (
                getattr(state, "name", None)
                and self.current_cd_drive_name != state.name):
            change_menu = False
            if not self.current_cd_drive_name:
                self.current_cd_drive_name = self.cdutil.get_default_cd_drive(
                )[1]
                change_menu = True
            elif state.name != "cd":
                self.current_cd_drive_name = state.name
                change_menu = True

            name = self.current_cd_drive_name
            tracks = len(self.file_menu.filelist.items)
            empty = self.cdutil.is_drive_empty(name)
            if name and empty != 1 and tracks == 0:
                change_menu = True

            if change_menu:
                id = self.cdutil.get_cd_drive_id_by_name(
                    self.current_cd_drive_name)
                self.current_cd_drive_id = id
                self.file_menu.selected_index = 0
                self.set_file_menu()

            self.set_screen_title()

    def set_screen_title(self):
        """ Set screen title """

        title = drive_name = self.current_cd_drive_name
        try:
            title = self.util.cd_titles[drive_name]
        except:
            pass
        self.screen_title.set_text(title)

    def eject_cd(self, state):
        """ Eject CD
        
        :param state: state object with drive info
        """
        if len(str(self.current_cd_drive_id)) == 0:
            return

        del self.util.cd_track_names_cache[self.current_cd_drive_id]
        if state == None or getattr(state, "no_physical_eject", None) == None:
            self.cdutil.eject_cd(int(self.current_cd_drive_id))
        self.util.cd_titles[
            self.current_cd_drive_name] = self.current_cd_drive_name
        self.file_menu.selected_index = 0
        self.set_file_menu()
        self.set_screen_title()

    def refresh_tracks(self, state):
        """ Refresh tracks menu
        
        :param state: not used
        """
        name = self.current_cd_drive_name
        if name and self.cdutil.is_drive_empty(name):
            s = State()
            s.no_physical_eject = True
            self.eject_cd(s)

        self.set_file_menu()
        self.set_screen_title()

    def set_file_menu(self):
        """ Set file menu """

        filelist = self.get_filelist()
        self.file_menu.filelist = filelist
        self.file_menu.update_buttons()
        page = filelist.get_current_page()
        self.file_menu.set_page(filelist.current_item_index_in_page, page)

    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)
예제 #17
0
파일: saver.py 프로젝트: Rucia1/Peppy
    def __init__(self, util, listeners, voice_assistant):
        """ Initializer
        
        :param util: utility object
        :param listener: screen menu event listener
        """
        self.util = util
        config = util.config
        screen_layout = BorderLayout(config[SCREEN_RECT])
        top = int((config[SCREEN_RECT].h * PERCENT_SAVERS) / 100)
        bottom = config[SCREEN_RECT].h - top
        screen_layout.set_pixel_constraints(top, bottom, 0, 0)
        
        layout = BorderLayout(screen_layout.TOP)
        layout.set_percent_constraints(PERCENT_TOP_HEIGHT, 0, 0, 0)
        
        Screen.__init__(self, util, "", PERCENT_TOP_HEIGHT, voice_assistant, "saver_title", title_layout=layout.TOP)
        factory = Factory(util)
        
        self.bounding_box = config[SCREEN_RECT]
        self.bgr = (0, 0, 0)
                
        self.saver_menu = SaverMenu(util, (0, 0, 0), layout.CENTER)
        self.add_component(self.saver_menu)
        
        d = config[COLORS][COLOR_DARK_LIGHT]
        c = config[COLORS][COLOR_CONTRAST]
        
        font_size = (layout.TOP.h * PERCENT_TITLE_FONT)/100.0
        label = config[LABELS][SCREENSAVER]
        self.screen_title.set_text(label)
        
        layout = BorderLayout(screen_layout.BOTTOM)
        layout.set_percent_constraints(PERCENT_DELAY_TITLE, PERCENT_DELAY_TITLE, 0, 0)
        self.delay_menu = SaverDelayMenu(util, (0, 0, 0), layout.CENTER)
        self.add_component(self.delay_menu)
        
        layout.TOP.y += 1
        layout.TOP.h -= 1
        self.saver_delay_title = factory.create_output_text("saver_delay_title", layout.TOP, d, c, int(font_size))
        label = config[LABELS][DELAY]
        self.saver_delay_title.set_text(label)
        self.add_component(self.saver_delay_title)
        
        buttons = factory.create_home_player_buttons(self, layout.BOTTOM, listeners)
        self.home_button = buttons[0]
        self.player_button = buttons[1]

        self.top_menu_enabled = True
예제 #18
0
class EqualizerMenu(Container):
    """ Equalizer Navigator Menu class """
    
    def __init__(self, util, handle_slider_event, bgr=None, bounding_box=None):
        """ Initializer
        
        :param util: utility object
        :param handle_slider_event: slider event handler
        :param listeners: menu listeners
        :param bgr: menu background
        :param bounding_box: bounding box
        """
        self.labels = ["31", "63", "125", "250", "500", "1k", "2k", "4k", "8k", "16k"]
          
        Container.__init__(self, util)
        name = "equalizermenu"
        self.factory = Factory(util)
        
        self.bounding_box = bounding_box
        self.bounding_box.y += 1
        self.bounding_box.h -= 1
        self.bgr_color = util.config[BACKGROUND][MENU_BGR_COLOR]

        self.eq_layout = BorderLayout(self.bounding_box)
        self.eq_layout.set_percent_constraints(0, 0, 5, 5)
        
        self.bands = 10
        self.sliders = self.add_sliders(handle_slider_event)
        self.current_slider = -1

        self.left_filler = Component(util, self.eq_layout.LEFT)
        self.left_filler.name = name + ".bgr.left"
        self.left_filler.bgr = self.bgr_color
        self.add_component(self.left_filler)

        self.right_filler = Component(util, self.eq_layout.RIGHT)
        self.right_filler.name = name + ".bgr.right"
        self.right_filler.bgr = self.bgr_color
        self.add_component(self.right_filler)
        
        self.SLOW_INCREMENT = 1
        self.FAST_INCREMENT = self.sliders[0].slider.knob_height/2
        
    def add_sliders(self, handle_slider_event):
        
        layout = GridLayout(self.eq_layout.CENTER)
        layout.set_pixel_constraints(1, self.bands, 0, 0)        
        layout.current_constraints = 0
        sliders = []

        for n in range(self.bands):        
            constr = layout.get_next_constraints()        
            s = self.factory.create_equalizer_slider(n, constr, "band", handle_slider_event, self.labels[n], self.bgr_color)
            s.slider.active = False
            s.content = None
            s.slider.content = None
            self.add_component(s)
            sliders.append(s)
        
        return sliders
    
    def set_bands(self, values):
        for n, s in enumerate(self.sliders):
            v = values[n]
            s.slider.set_position(v)
            s.slider.update_position()
            s.set_value(str(v))
            s.slider.set_knob_off()
            self.current_slider = -1
    
    def set_parent_screen(self, scr):
        """ Add parent screen

        :param scr: parent screen
        """
        self.left_filler.parent_screen = scr
        self.right_filler.parent_screen = scr
        for s in self.sliders:
            s.slider.parent_screen = scr
            s.top.parent_screen = scr
            s.bottom.parent_screen = scr

    def handle_event(self, event):
        """ Menu event handler
        
        :param event: menu event
        """
        if not self.visible: return
        
        if event.type == USER_EVENT_TYPE and event.sub_type == SUB_TYPE_KEYBOARD:
            key_events = [kbd_keys[KEY_LEFT], kbd_keys[KEY_RIGHT], kbd_keys[KEY_UP], kbd_keys[KEY_DOWN], kbd_keys[KEY_PAGE_UP], kbd_keys[KEY_PAGE_DOWN]]
            if event.keyboard_key not in key_events:
                return
            
            if event.action == pygame.KEYUP:
                self.key_up(event)
            elif event.action == pygame.KEYDOWN:
                self.key_down(event)                
        else:
            if not self.bounding_box.collidepoint(event.pos):
                return
            
            if event.type == pygame.MOUSEBUTTONDOWN:
                selected_slider = self.current_slider                
                for i, b in enumerate(self.sliders):
                    if b.slider.bounding_box.collidepoint(event.pos):
                        selected_slider = i
                        break
                
                if selected_slider != self.current_slider:
                    self.deactivate_current_slider()
                    self.current_slider = selected_slider

            Container.handle_event(self, event)
            
            if event.type == pygame.MOUSEBUTTONUP:
                slider = self.sliders[self.current_slider].slider
                slider.set_knob_on()
                slider.notify_slide_listeners()

    def key_up(self, event):
        avoided_keys = [kbd_keys[KEY_UP], kbd_keys[KEY_DOWN], kbd_keys[KEY_PAGE_UP], kbd_keys[KEY_PAGE_DOWN]]
        if self.current_slider == -1 and (event.keyboard_key in avoided_keys): return
        
        self.deactivate_current_slider()
        if event.keyboard_key == kbd_keys[KEY_LEFT]:
            if self.current_slider == 0 or self.current_slider == -1:
                self.current_slider = len(self.sliders) - 1
            else:
                self.current_slider -= 1                
        elif event.keyboard_key == kbd_keys[KEY_RIGHT]:
            if self.current_slider == len(self.sliders) - 1:
                self.current_slider = 0
            else:
                self.current_slider += 1
                
        self.activate_slider()

    def key_down(self, event):
        if self.current_slider == -1: return
        
        slider = self.sliders[self.current_slider].slider
        
        if event.keyboard_key == kbd_keys[KEY_UP]:            
            slider.release_action((slider.knob_x, slider.last_knob_position + slider.knob_height/2 - self.SLOW_INCREMENT))
        elif event.keyboard_key == kbd_keys[KEY_DOWN] and event.action == pygame.KEYDOWN:
            slider.release_action((slider.knob_x, slider.last_knob_position + slider.knob_height/2 + self.SLOW_INCREMENT))
        elif event.keyboard_key == kbd_keys[KEY_PAGE_UP] and event.action == pygame.KEYDOWN:
            slider.release_action((slider.knob_x, slider.last_knob_position - self.FAST_INCREMENT))
        elif event.keyboard_key == kbd_keys[KEY_PAGE_DOWN] and event.action == pygame.KEYDOWN:
            slider.release_action((slider.knob_x, slider.last_knob_position + slider.knob_height/2 + self.FAST_INCREMENT))
        
        slider.set_knob_on()              

    def deactivate_current_slider(self):
        if self.current_slider == -1:
            return
        
        slider = self.sliders[self.current_slider].slider
        slider.release_action((slider.knob_x, slider.last_knob_position))
        slider.clean_draw_update()
        
    def activate_slider(self):
        slider = self.sliders[self.current_slider].slider
        slider.press_action()
        slider.clean_draw_update()
    
    def add_menu_observers(self, update_observer, redraw_observer):
        for b in self.sliders:
            b.slider.add_slide_listener(update_observer)
            b.slider.add_knob_listener(update_observer)
            b.slider.add_press_listener(update_observer)
            b.slider.add_motion_listener(update_observer)
            b.web_seek_listener = update_observer
예제 #19
0
파일: station.py 프로젝트: danpgh/Peppy
    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.info_button = None
        self.info_popup = None
        self.start_screensaver = listeners[SCREENSAVER]
        bottom_layout = BorderLayout(layout.BOTTOM)
        bottom_layout.set_percent_constraints(0, 0, 0, POPUP_WIDTH_PERCENT)

        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
예제 #20
0
    def __init__(self,
                 util,
                 title_key,
                 percent_bottom_height=0,
                 voice_assistant=None,
                 screen_title_name="screen_title",
                 create_dynamic_title=False,
                 title_layout=None,
                 title=None):
        """ Initializer
        
        :param util: utility object
        :param title_key: the resource bundle key for the screen title
        """
        Container.__init__(self, util)
        self.util = util
        factory = Factory(util)
        self.config = util.config
        self.bounding_box = util.screen_rect
        self.bgr = (0, 0, 0)
        self.layout = BorderLayout(util.screen_rect)
        self.layout.set_percent_constraints(PERCENT_TOP_HEIGHT,
                                            percent_bottom_height, 0, 0)
        self.voice_assistant = voice_assistant

        self.font_size = int((self.layout.TOP.h * PERCENT_TITLE_FONT) / 100.0)
        d = self.config[COLORS][COLOR_DARK_LIGHT]
        c = self.config[COLORS][COLOR_CONTRAST]

        t_layout = self.layout.TOP
        if title_layout:
            t_layout = title_layout

        if create_dynamic_title:
            self.screen_title = factory.create_dynamic_text(
                screen_title_name, t_layout, d, c, self.font_size)
        else:
            self.screen_title = factory.create_output_text(
                screen_title_name, t_layout, d, c, self.font_size)

        if title:
            self.screen_title.set_text(title)
        else:
            if title_key and len(title_key) > 0:
                try:
                    label = self.config[LABELS][title_key]
                    self.screen_title.set_text(label)
                except:
                    pass

        if voice_assistant:
            self.screen_title.add_select_listener(self.handle_voice_assistant)
            self.layout.TOP.w += 1
            self.voice_command = factory.create_output_text(
                "voice_command", self.layout.TOP, d, c, self.font_size)
            self.voice_command.add_select_listener(self.handle_voice_assistant)
            self.voice_assistant.add_text_recognized_listener(
                self.text_recognized)
            self.voice_assistant.assistant.add_start_conversation_listener(
                self.start_conversation)
            self.voice_assistant.assistant.add_stop_conversation_listener(
                self.stop_conversation)

        if voice_assistant and voice_assistant.is_running():
            self.title_selected = False
        else:
            self.title_selected = True

        self.draw_title_bar()
        self.player_screen = False
        self.update_web_observer = None
        self.update_web_title = None

        self.loading_listeners = []
        self.LOADING = util.config[LABELS][KEY_LOADING]
        self.factory = factory
예제 #21
0
class TopicDetailNavigator(Container):
    """ Topic detail navigator """
    def __init__(self, util, bounding_box, listeners):
        """ Initializer

        :param util: utility object
        :param bounding_box: bounding box
        :param listeners: buttons listeners
        """
        Container.__init__(self, util)
        self.factory = Factory(util)
        self.name = "collection.navigator"
        self.content = bounding_box
        self.content_x = bounding_box.x
        self.content_y = bounding_box.y
        self.listeners = listeners
        self.menu_buttons = []
        self.config = util.config
        self.use_web = self.config[USAGE][USE_WEB]
        self.bgr = util.config[COLORS][COLOR_DARK_LIGHT]
        self.arrow_layout = BorderLayout(bounding_box)
        self.arrow_layout.set_percent_constraints(0, 0, PERCENT_ARROW_WIDTH,
                                                  PERCENT_ARROW_WIDTH)
        self.update_observer = None
        self.redraw_observer = None
        self.menu_buttons = []

        constr = self.arrow_layout.LEFT
        self.left_button = self.factory.create_page_down_button(
            constr, "0", 40, 100)
        self.left_button.add_release_listener(self.listeners[GO_LEFT_PAGE])
        self.add_component(self.left_button)
        self.menu_buttons.append(self.left_button)

        constr = self.arrow_layout.RIGHT
        self.right_button = self.factory.create_page_up_button(
            constr, "0", 40, 100)
        self.right_button.add_release_listener(self.listeners[GO_RIGHT_PAGE])
        self.add_component(self.right_button)
        self.menu_buttons.append(self.right_button)

        layout = GridLayout(self.arrow_layout.CENTER)
        layout.set_pixel_constraints(1, 5, 1, 0)
        layout.current_constraints = 0

        self.add_button(KEY_HOME, KEY_HOME, layout, self.listeners[KEY_HOME])
        self.add_button(KEY_BACK, KEY_BACK, layout, self.listeners[KEY_BACK])
        self.add_button(COLLECTION, KEY_PARENT, layout,
                        self.listeners[COLLECTION])
        self.add_button(KEY_LIST, KEY_MENU, layout,
                        self.listeners[COLLECTION_TOPIC])
        self.add_button(KEY_PLAYER, KEY_PLAY_PAUSE, layout,
                        self.listeners[KEY_PLAYER])

        if self.use_web and self.update_observer != None:
            self.add_observers(self.update_observer, self.redraw_observer)

    def add_button(self, img_name, key, layout, listener):
        """ Add button to the navigator

        :param img_name: button image name
        :param key: keyboard key
        :param layout: button layout
        :param listener: button listener
        """
        c = layout.get_next_constraints()
        b = self.factory.create_button(img_name,
                                       key,
                                       c,
                                       listener,
                                       self.bgr,
                                       source="navigator",
                                       image_size_percent=IMAGE_SIZE_PERCENT)
        self.add_component(b)
        self.menu_buttons.append(b)

    def add_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
        """
        if self.update_observer == None:
            self.update_observer = update_observer
            self.redraw_observer = redraw_observer

        for b in self.menu_buttons:
            self.add_button_observers(b, update_observer, redraw_observer)
예제 #22
0
    def __init__(self, util, connected_cd_drives, bounding_box, listeners,
                 bgr):
        """ Initializer
        
        :param util: utility object
        :param bounding_box: bounding box
        :param listeners: buttons listeners
        :param bgr: menu background        
        """
        Container.__init__(self, util)
        self.factory = Factory(util)
        self.name = "navigator"
        self.content = bounding_box
        self.content_x = bounding_box.x
        self.content_y = bounding_box.y
        self.menu_buttons = []
        self.config = util.config

        arrow_layout = BorderLayout(bounding_box)
        arrow_layout.set_percent_constraints(0, 0, PERCENT_ARROW_WIDTH,
                                             PERCENT_ARROW_WIDTH)

        constr = arrow_layout.LEFT
        self.left_button = self.factory.create_page_down_button(
            constr, "0", 40, 100)
        self.left_button.add_release_listener(listeners[GO_LEFT_PAGE])
        self.add_component(self.left_button)
        self.menu_buttons.append(self.left_button)

        constr = arrow_layout.RIGHT
        self.right_button = self.factory.create_page_up_button(
            constr, "0", 40, 100)
        self.right_button.add_release_listener(listeners[GO_RIGHT_PAGE])
        self.add_component(self.right_button)
        self.menu_buttons.append(self.right_button)

        layout = GridLayout(arrow_layout.CENTER)
        p = self.config[AUDIO][PLAYER_NAME]
        show_drives = connected_cd_drives > 1 and (p == VLC or p == MPD)

        if show_drives:
            layout.set_pixel_constraints(1, 5, 1, 0)
        else:
            layout.set_pixel_constraints(1, 4, 1, 0)
        layout.current_constraints = 0
        image_size = 56

        constr = layout.get_next_constraints()
        self.home_button = self.factory.create_button(
            KEY_HOME,
            KEY_HOME,
            constr,
            listeners[KEY_HOME],
            bgr,
            image_size_percent=image_size)
        self.add_component(self.home_button)
        self.menu_buttons.append(self.home_button)

        if show_drives:
            constr = layout.get_next_constraints()
            self.cd_drives_button = self.factory.create_button(
                KEY_CD_PLAYERS,
                KEY_ROOT,
                constr,
                listeners[KEY_CD_PLAYERS],
                bgr,
                image_size_percent=image_size)
            self.add_component(self.cd_drives_button)
            self.menu_buttons.append(self.cd_drives_button)

        constr = layout.get_next_constraints()
        self.refresh_button = self.factory.create_button(
            KEY_REFRESH,
            KEY_SETUP,
            constr,
            listeners[KEY_REFRESH],
            bgr,
            image_size_percent=image_size)
        self.add_component(self.refresh_button)
        self.menu_buttons.append(self.refresh_button)

        constr = layout.get_next_constraints()
        self.eject_button = self.factory.create_button(
            KEY_EJECT,
            KEY_PARENT,
            constr,
            listeners[KEY_EJECT],
            bgr,
            image_size_percent=image_size)
        self.add_component(self.eject_button)
        self.menu_buttons.append(self.eject_button)

        constr = layout.get_next_constraints()
        self.back_button = self.factory.create_button(
            KEY_BACK,
            KEY_BACK,
            constr,
            None,
            bgr,
            image_size_percent=image_size)
        self.back_button.add_release_listener(listeners[GO_BACK])
        self.back_button.add_release_listener(listeners[KEY_PLAYER])
        self.add_component(self.back_button)
        self.menu_buttons.append(self.back_button)