Beispiel #1
0
class BookAuthor(MenuScreen):
    """ Authors screen """
    def __init__(self, util, listeners, ch, f, go_author, parser, base_url,
                 voice_assistant, d):
        """ Initializer
        
        :param util: utility object
        :param listeners: screen listeners
        :param ch: selected character
        :param f: selected filter
        :param go_authors: callback
        :param parser: authors parser
        :param base_url: url
        :param d: dictionary with menu button flags 
        """
        self.util = util
        self.factory = Factory(util)
        self.base_url = base_url
        self.config = util.config

        self.parser = parser
        self.current_author_char = ch
        self.current_author_filter = f
        self.go_author = go_author
        self.author_cache = {}
        self.title = self.config[LABELS][KEY_AUTHORS]

        MenuScreen.__init__(self, util, listeners, MENU_ROWS, MENU_COLUMNS,
                            voice_assistant, d, self.turn_page)
        m = self.create_book_author_menu_button

        self.navigator = BookNavigator(util, self.layout.BOTTOM, listeners,
                                       d[4])
        self.back_button = self.navigator.get_button_by_name(KEY_BACK)
        self.left_button = self.navigator.get_button_by_name(KEY_PAGE_DOWN)
        self.right_button = self.navigator.get_button_by_name(KEY_PAGE_UP)
        self.add_navigator(self.navigator)

        font_size = int(((self.menu_layout.h / MENU_ROWS) / 100) *
                        self.config[FONT_HEIGHT_PERCENT])
        self.authors_menu = MultiPageMenu(util,
                                          self.next_page,
                                          self.previous_page,
                                          self.set_title,
                                          self.reset_title,
                                          self.go_to_page,
                                          m,
                                          MENU_ROWS,
                                          MENU_COLUMNS,
                                          None, (0, 0, 0),
                                          self.menu_layout,
                                          font_size=font_size)
        self.set_menu(self.authors_menu)

    def create_book_author_menu_button(self, s, constr, action, scale,
                                       font_size):
        """ Create Author Menu button

        :param s: button state
        :param constr: bounding box
        :param action: button event listener
        :param show_img: True - show image, False - don't show image
        :param show_label: True - show label, False - don't show label
        
        :return: genre menu button
        """
        s.bounding_box = constr
        s.img_x = None
        s.img_y = None
        s.auto_update = True
        s.show_bgr = True
        s.show_img = False
        s.show_label = True
        s.text_color_normal = self.config[COLORS][COLOR_BRIGHT]
        s.text_color_selected = self.config[COLORS][COLOR_CONTRAST]
        s.text_color_disabled = self.config[COLORS][COLOR_MEDIUM]
        s.text_color_current = s.text_color_normal
        s.fixed_height = font_size

        button = Button(self.util, s)
        button.add_release_listener(action)
        return button

    def create_book_author_items(self, authors):
        """ Create dictionary with author books

        :param authors: list of author books

        :return: dictionary with author books
        """
        items = {}
        for i, g in enumerate(authors):
            state = State()
            state.name = g[AUTHOR_NAME]
            state.url = g[AUTHOR_URL] + "/"
            state.author_books = int(g[AUTHOR_BOOKS])
            try:
                state.l_name = state.name + " (" + g[AUTHOR_BOOKS] + ")"
            except:
                state.l_name = state.name
            state.bgr = self.config[COLORS][COLOR_DARK]
            state.img_x = None
            state.img_y = None
            state.auto_update = True
            state.show_bgr = True
            state.show_img = False
            state.show_label = True
            state.comparator_item = state.name
            state.index = i
            items[state.name] = state
        return items

    def set_current(self, ch=None, f=None):
        """ Apply selected character and filter
        
        :param ch: selected character
        :param f: selected filter
        """
        if not ch and not f:
            return

        self.set_loading(self.config[LABELS][KEY_AUTHORS])

        self.total_pages = 0
        self.current_page = 1
        self.current_author_char = ch
        self.current_author_filter = f

        try:
            self.author_cache[ch]
        except:
            self.get_authors()

        self.turn_page()
        self.reset_loading()

    def get_authors(self):
        """ Get authors from parser """

        self.parser.author_parser.current_author_char = self.current_author_char
        self.parser.author_parser.url = self.base_url
        authors = self.parser.get_authors()
        if authors:
            self.author_cache[self.current_author_char] = authors

    def turn_page(self):
        """ Turn authors page """

        self.authors_menu.set_items({}, 0, self.go_author)

        filtered_authors = []
        for a in self.author_cache[self.current_author_char]:
            if self.current_author_filter:
                if a[AUTHOR_NAME].startswith(self.current_author_filter):
                    filtered_authors.append(a)
            else:
                filtered_authors.append(a)

        start = (self.current_page - 1) * PAGE_SIZE
        end = self.current_page * PAGE_SIZE
        page = filtered_authors[start:end]
        self.author_dict = self.create_book_author_items(page)
        self.authors_menu.set_items(self.author_dict, 0, self.go_author, False)
        self.authors_menu.align_content(ALIGN_LEFT)
        self.total_pages = math.ceil(len(filtered_authors) / PAGE_SIZE)

        left = str(self.current_page - 1)
        if self.total_pages == 0:
            right = "0"
        else:
            right = str(self.total_pages - self.current_page)

        self.left_button.change_label(left)
        self.right_button.change_label(right)
        self.set_title(self.current_page)

        if self.authors_menu.get_selected_item() != None:
            self.navigator.unselect()
        else:
            if not self.navigator.is_selected():
                self.back_button.set_selected(True)
                self.back_button.clean_draw_update()

        self.authors_menu.clean_draw_update()

        self.link_borders()

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

        :param event: the event to handle
        """
        self.handle_event_common(event)

    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
        """
        self.navigator.add_observers(update_observer, redraw_observer)
        self.authors_menu.add_menu_loaded_listener(redraw_observer)
        self.authors_menu.add_menu_observers(update_observer,
                                             redraw_observer,
                                             release=False)
Beispiel #2
0
class WiFiScreen(MenuScreen):
    """ Wi-Fi Screen """
    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.listeners = listeners
        self.factory = Factory(util)
        self.go_home = listeners[KEY_HOME]
        self.go_keyboard = listeners[KEY_KEYBOARD_KEY]
        self.keyboard_callback = listeners[KEY_CALLBACK]

        self.wifi_selection_listeners = []

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

        d = [MENU_ROWS_WIFI, MENU_COLUMNS_WIFI]
        MenuScreen.__init__(self,
                            util,
                            listeners,
                            MENU_ROWS_WIFI,
                            MENU_COLUMNS_WIFI,
                            voice_assistant,
                            d,
                            self.turn_page,
                            page_in_title=False,
                            show_loading=False)
        self.title = self.config[LABELS]["select.wifi"]
        self.set_title(1)

        listeners[KEY_REFRESH] = self.set_current
        listeners[KEY_SORT] = self.sort_abc
        self.navigator = WiFiNavigator(self.util, self.layout.BOTTOM,
                                       listeners, PAGE_SIZE_WIFI + 1)
        self.add_component(self.navigator)
        self.network_button = self.navigator.get_button_by_name(KEY_NETWORK)

        m = self.factory.create_wifi_menu_button
        font_height = 32
        font_size = int(
            ((self.menu_layout.h / MENU_ROWS_WIFI) / 100) * font_height)
        self.wifi_menu = MultiPageMenu(util,
                                       self.next_page,
                                       self.previous_page,
                                       self.set_title,
                                       self.reset_title,
                                       self.go_to_page,
                                       m,
                                       MENU_ROWS_WIFI,
                                       MENU_COLUMNS_WIFI,
                                       None, (0, 0, 0),
                                       self.menu_layout,
                                       align=ALIGN_CENTER,
                                       font_size=font_size)
        self.set_menu(self.wifi_menu)

        self.original_networks = None
        self.networks = None
        self.sort_direction = False
        self.current_network = None
        self.link_borders()

    def set_current(self, state):
        """ Set current state

        :param state: button state
        """
        self.set_loading(self.title)
        info = self.wifi_util.get_wifi_networks()

        self.original_networks = info["networks"]

        if not self.original_networks:
            self.reset_loading()
            if not self.navigator.is_selected():
                self.network_button.set_selected(True)
            self.clean_draw_update()
            return

        self.networks = self.sort_networks(SORT_ALPHABETICALLY)
        self.current_network = info["profile"]
        self.total_pages = math.ceil(len(self.networks) / PAGE_SIZE_WIFI)
        self.reset_loading()

        self.current_page = self.wifi_util.get_page_num(
            self.current_network, self.networks)
        self.turn_page()

    def sort_networks(self, order):
        """ Sort networks

        :param order: sort order
        :return: sorted networks
        """
        sorted_networks = []

        if order == SORT_ALPHABETICALLY:
            sorted_networks = sorted(self.original_networks,
                                     key=lambda i: i["name"],
                                     reverse=self.sort_direction)
        else:
            sorted_networks = sorted(self.original_networks,
                                     key=lambda i: i["strength"],
                                     reverse=self.sort_direction)

        states = {}
        h = self.layout.CENTER.h / MENU_ROWS_WIFI
        bb = pygame.Rect(0, 0, h, h)
        for i, n in enumerate(sorted_networks):
            s = self.wifi_util.get_network_info(i, n["name"], n["strength"],
                                                bb)
            states[s.name] = s

        return states

    def sort_abc(self, state):
        """ Sort in alphabetical order

        :param state: button state
        """
        self.sort(SORT_ALPHABETICALLY)

    def select_network(self, state=None):
        """ Select network from menu

        :param state: button state
        """
        self.current_network = state.name
        self.notify_wifi_selection_listeners(self.current_network)
        state.title = self.config[LABELS]["enter.password"]
        state.callback = self.keyboard_callback
        self.go_keyboard(state)

    def sort(self, order):
        """ Sort by order

        :param order: sort order
        :return:
        """
        self.sort_direction = not self.sort_direction
        self.current_page = 1
        self.networks = self.sort_networks(order)
        self.turn_page()

    def turn_page(self):
        """ Turn page """

        p = self.wifi_util.get_network_page(self.current_page, self.networks)
        self.wifi_menu.set_items(p, 0, self.select_network, False)

        keys = list(p.keys())

        if len(keys) != 0 and self.navigator and self.total_pages > 1:
            self.navigator.get_button_by_name(KEY_PAGE_DOWN).change_label(
                str(self.current_page - 1))
            self.navigator.get_button_by_name(KEY_PAGE_UP).change_label(
                str(self.total_pages - self.current_page))

        self.set_title(self.current_page)
        self.wifi_menu.clean_draw_update()

        if hasattr(self, "update_observer"):
            self.wifi_menu.add_menu_observers(self.update_observer,
                                              self.redraw_observer)

        self.wifi_menu.unselect()
        for b in self.wifi_menu.buttons.values():
            if self.current_network == b.state.name:
                self.wifi_menu.select_by_index(b.state.index)
                break

        if self.wifi_menu.get_selected_item() != None:
            self.navigator.unselect()
        else:
            if not self.navigator.is_selected():
                self.network_button.set_selected(True)

        self.link_borders()

    def add_wifi_selection_listener(self, listener):
        """ Add listener

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

    def notify_wifi_selection_listeners(self, selected_wifi):
        """ Notify all listeners

        :param selected_wifi:
        """
        for listener in self.wifi_selection_listeners:
            listener(selected_wifi)

    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
        """
        MenuScreen.add_screen_observers(self, update_observer, redraw_observer)
        self.update_observer = update_observer
        self.redraw_observer = redraw_observer
        self.add_loading_listener(redraw_observer)
        self.navigator.add_observers(update_observer, redraw_observer)
Beispiel #3
0
class RadioGroupScreen(MenuScreen):
    """ Radio group screen """
    def __init__(self, util, listeners, voice_assistant):
        self.util = util
        self.config = util.config
        self.groups_list = self.util.get_stations_folders()
        self.factory = Factory(util)
        d = [MENU_ROWS, MENU_COLUMNS]
        MenuScreen.__init__(self,
                            util,
                            listeners,
                            MENU_ROWS,
                            MENU_COLUMNS,
                            voice_assistant,
                            d,
                            self.turn_page,
                            page_in_title=False)
        self.total_pages = math.ceil(len(self.groups_list) / PAGE_SIZE)
        self.title = util.get_stations_top_folder()
        m = self.create_genre_menu_button
        label_area = (
            (self.menu_layout.h / MENU_ROWS) / 100) * (100 - ICON_AREA)
        font_size = int((label_area / 100) * FONT_HEIGHT)

        self.navigator = RadioGroupNavigator(self.util, self.layout.BOTTOM,
                                             listeners, self.total_pages)
        self.add_navigator(self.navigator)
        self.player_button = self.navigator.get_button_by_name(KEY_PLAYER)
        if self.total_pages > 1:
            self.left_button = self.navigator.get_button_by_name(KEY_PAGE_DOWN)
            self.right_button = self.navigator.get_button_by_name(KEY_PAGE_UP)

        self.groups_menu = MultiPageMenu(util,
                                         self.next_page,
                                         self.previous_page,
                                         self.set_title,
                                         self.reset_title,
                                         self.go_to_page,
                                         m,
                                         MENU_ROWS,
                                         MENU_COLUMNS,
                                         None, (0, 0, 0, 0),
                                         self.menu_layout,
                                         align=ALIGN_CENTER,
                                         font_size=font_size)
        self.groups_menu.add_listener(listeners[KEY_GENRE])
        self.set_menu(self.groups_menu)

        current_name = self.get_current_group_name()

        if current_name == None:
            self.current_page = 1
        else:
            try:
                current_group_index = self.groups_list.index(current_name)
                self.current_page = int(current_group_index / PAGE_SIZE) + 1
            except:
                current_group_index = 0

        self.turn_page()

    def create_genre_menu_button(self, s, constr, action, scale, font_size):
        """ Create Genre Menu button

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

        :return: genre menu button
        """
        s.padding = BUTTON_PADDING
        s.image_area_percent = ICON_AREA
        s.fixed_height = font_size
        s.v_align = CENTER

        return self.factory.create_menu_button(s,
                                               constr,
                                               action,
                                               scale,
                                               font_size=font_size)

    def get_current_group_name(self):
        group = self.util.get_current_genre()
        if group != None:
            return group.name
        else:
            return None

    def get_page(self):
        start = (self.current_page - 1) * PAGE_SIZE
        end = self.current_page * PAGE_SIZE
        tmp_layout = self.groups_menu.get_layout(self.groups_list)
        button_rect = tmp_layout.constraints[0]
        image_box = self.factory.get_icon_bounding_box(button_rect,
                                                       ICON_LOCATION,
                                                       ICON_AREA, ICON_SIZE,
                                                       BUTTON_PADDING)
        groups_dict = self.util.load_stations_folders(image_box)

        return self.util.get_radio_group_slice(groups_dict, start, end)

    def turn_page(self):
        """ Turn book genre page """

        group_page = self.get_page()
        self.groups_menu.set_items(group_page, 0, self.change_group, False)
        current_name = self.get_current_group_name()
        self.current_genre = None
        try:
            self.current_genre = group_page[current_name]
        except:
            pass
        self.groups_menu.item_selected(self.current_genre)

        if self.navigator and self.total_pages > 1:
            self.left_button.change_label(str(self.current_page - 1))
            self.right_button.change_label(
                str(self.total_pages - self.current_page))

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

        self.groups_menu.clean_draw_update()
        menu_selected = self.groups_menu.get_selected_item() != None
        if menu_selected:
            self.navigator.unselect()

        self.link_borders()
        navigator_selected = self.navigator.is_selected()
        if (len(group_page) == 0 or
            (not menu_selected and not navigator_selected)) and self.navigator:
            self.navigator.unselect()
            self.player_button.set_selected(True)
            self.player_button.clean_draw_update()

        self.set_title(self.current_page)

    def change_group(self, state):
        """ Change group event listener
         
        :param state: button state
        """
        if not self.visible:
            return
        self.current_genre = state

        key = STATIONS + "." + self.config[CURRENT][LANGUAGE]
        self.config[key][CURRENT_STATIONS] = state.genre
        state.source = GENRE
        self.groups_menu.notify_listeners(state)

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

        :param event: the event to handle
        """
        self.handle_event_common(event)

    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
        """
        self.navigator.add_observers(update_observer, redraw_observer)
        self.groups_menu.add_menu_observers(update_observer,
                                            redraw_observer,
                                            release=False)
Beispiel #4
0
class BluetoothScreen(MenuScreen):
    """ Bluetooth Screen """
    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.listeners = listeners
        self.factory = Factory(util)
        self.go_home = listeners[KEY_HOME]
        self.go_network = listeners[KEY_NETWORK]
        self.go_player = listeners[KEY_PLAYER]

        self.wifi_selection_listeners = []

        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)

        d = [MENU_ROWS_BLUETOOTH, MENU_COLUMNS_BLUETOOTH]
        MenuScreen.__init__(self,
                            util,
                            listeners,
                            MENU_ROWS_BLUETOOTH,
                            MENU_COLUMNS_BLUETOOTH,
                            voice_assistant,
                            d,
                            self.turn_page,
                            page_in_title=False,
                            show_loading=False)
        self.title = self.config[LABELS]["select.bluetooth.device"]
        self.set_title(1)

        listeners[KEY_HOME] = self.before_home
        listeners[KEY_NETWORK] = self.before_network
        listeners[KEY_PLAYER] = self.before_player
        listeners[KEY_REFRESH] = self.set_current

        self.navigator = BluetoothNavigator(self.util, self.layout.BOTTOM,
                                            listeners, PAGE_SIZE_BLUETOOTH + 1)
        self.add_navigator(self.navigator)
        self.network_button = self.navigator.get_button_by_name(KEY_NETWORK)
        self.left_button = self.navigator.get_button_by_name(KEY_PAGE_DOWN)
        self.right_button = self.navigator.get_button_by_name(KEY_PAGE_UP)

        m = self.factory.create_wifi_menu_button
        font_height = 32
        font_size = int(
            ((self.menu_layout.h / MENU_ROWS_BLUETOOTH) / 100) * font_height)
        self.bluetooth_menu = MultiPageMenu(util,
                                            self.next_page,
                                            self.previous_page,
                                            self.set_title,
                                            self.reset_title,
                                            self.go_to_page,
                                            m,
                                            MENU_ROWS_BLUETOOTH,
                                            MENU_COLUMNS_BLUETOOTH,
                                            None, (0, 0, 0),
                                            self.menu_layout,
                                            align=ALIGN_LEFT,
                                            font_size=font_size)
        self.set_menu(self.bluetooth_menu)

        self.devices = None
        self.networks = None
        self.sort_direction = False
        self.current_device = None

    def set_current(self, state):
        """ Set current state

        :param state: button state
        """
        self.set_loading(self.title)
        self.bluetooth_util.start_scan()
        self.devices = self.bluetooth_util.get_available_devices()

        if not self.devices:
            self.reset_loading()
            self.left_button.change_label("0")
            self.right_button.change_label("0")
            if not self.navigator.is_selected():
                self.network_button.set_selected(True)
                self.link_borders()
            self.clean_draw_update()
            return

        d = self.bluetooth_util.get_connected_device()
        if d:
            self.current_device = d
        else:
            self.current_device = None

        self.total_pages = math.ceil(len(self.devices) / PAGE_SIZE_BLUETOOTH)
        self.reset_loading()

        self.current_page = self.bluetooth_util.get_page_num(
            self.current_device, self.devices)
        if not self.current_page:
            self.current_page = 1

        self.turn_page()

    def select_network(self, state=None):
        """ Select network from menu

        :param state: button state
        """
        if hasattr(state,
                   "mac_address") and self.bluetooth_util.is_device_connected(
                       state.mac_address):
            self.before_network(state)
            return

        state.source = "bluetooth"
        self.notify_wifi_selection_listeners(state.name)
        self.before_network(state)

    def turn_page(self):
        """ Turn page """

        p = self.bluetooth_util.get_page(self.current_page, self.devices)
        try:
            self.bluetooth_menu.set_items(p, 0, self.select_network, False)
        except Exception as e:
            logging.debug(e)

        if len(self.devices) != 0 and self.navigator and self.total_pages > 1:
            self.left_button.change_label(str(self.current_page - 1))
            self.right_button.change_label(
                str(self.total_pages - self.current_page))

        self.set_title(self.current_page)
        self.bluetooth_menu.clean_draw_update()

        if hasattr(self, "update_observer"):
            self.bluetooth_menu.add_menu_observers(self.update_observer,
                                                   self.redraw_observer)

        self.bluetooth_menu.unselect()
        for b in self.bluetooth_menu.buttons.values():
            if self.current_device and self.current_device[
                    "name"] == b.state.name:
                self.bluetooth_menu.select_by_index(b.state.index)
                break

        if self.bluetooth_menu.get_selected_item() != None:
            self.navigator.unselect()
        else:
            if not self.navigator.is_selected():
                self.network_button.set_selected(True)

        self.link_borders()

    def before_home(self, state):
        """ Stop bluetooth scanning and go to home screen

        :param state: button state
        """
        self.bluetooth_util.stop_scan()
        self.go_home(state)

    def before_network(self, state):
        """ Stop bluetooth scanning and go to network screen

        :param state: button state
        """
        self.bluetooth_util.stop_scan()
        self.go_network(state)

    def before_player(self, state):
        """ Stop bluetooth scanning and go to player screen

        :param state: button state
        """
        self.bluetooth_util.stop_scan()
        self.go_player(state)

    def add_bluetooth_selection_listener(self, listener):
        """ Add listener

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

    def notify_wifi_selection_listeners(self, selected_wifi):
        """ Notify all listeners

        :param selected_wifi:
        """
        for listener in self.wifi_selection_listeners:
            listener(selected_wifi)

    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
        """
        MenuScreen.add_screen_observers(self, update_observer, redraw_observer)
        self.update_observer = update_observer
        self.redraw_observer = redraw_observer
        self.add_loading_listener(redraw_observer)
        self.navigator.add_observers(update_observer, redraw_observer)

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

        :param event: the event to handle
        """
        self.handle_event_common(event)
Beispiel #5
0
class BookGenre(MenuScreen):
    """ Book genre screen """
    def __init__(self, util, listeners, go_book_by_genre, genres, base_url,
                 voice_assistant, d):
        self.util = util
        self.go_book_by_genre = go_book_by_genre
        self.config = util.config
        self.genres_list = genres
        self.base_url = base_url
        self.factory = Factory(util)
        MenuScreen.__init__(self, util, listeners, MENU_ROWS, MENU_COLUMNS,
                            voice_assistant, d, self.turn_page)
        self.total_pages = math.ceil(len(genres) / PAGE_SIZE)
        self.title = self.config[LABELS][KEY_CHOOSE_GENRE]

        self.navigator = BookNavigator(util, self.layout.BOTTOM, listeners,
                                       d[4])
        self.back_button = self.navigator.get_button_by_name(KEY_BACK)
        self.left_button = self.navigator.get_button_by_name(KEY_PAGE_DOWN)
        self.right_button = self.navigator.get_button_by_name(KEY_PAGE_UP)
        self.add_navigator(self.navigator)

        m = self.create_book_genre_menu_button
        font_size = int(((self.menu_layout.h / MENU_ROWS) / 100) *
                        self.config[FONT_HEIGHT_PERCENT])
        self.genre_menu = MultiPageMenu(util,
                                        self.next_page,
                                        self.previous_page,
                                        self.set_title,
                                        self.reset_title,
                                        self.go_to_page,
                                        m,
                                        MENU_ROWS,
                                        MENU_COLUMNS,
                                        None, (0, 0, 0, 0),
                                        self.menu_layout,
                                        font_size=font_size)
        self.set_menu(self.genre_menu)

        self.turn_page()

    def create_book_genre_menu_button(self,
                                      s,
                                      constr,
                                      action,
                                      show_img=True,
                                      show_label=True):
        """ Create Genre Menu button

        :param s: button state
        :param constr: bounding box
        :param action: button event listener
        :param show_img: True - show image, False - don't show image
        :param show_label: True - show label, False - don't show label

        :return: genre menu button
        """
        s.bounding_box = constr
        s.img_x = None
        s.img_y = None
        s.auto_update = True
        s.show_bgr = True
        s.show_img = show_img
        s.show_label = show_label
        s.text_color_normal = self.config[COLORS][COLOR_BRIGHT]
        s.text_color_selected = self.config[COLORS][COLOR_CONTRAST]
        s.text_color_disabled = self.config[COLORS][COLOR_MEDIUM]
        s.text_color_current = s.text_color_normal
        s.label_text_height = 35
        s.bgr = self.config[BACKGROUND][MENU_BGR_COLOR]

        button = Button(self.util, s)
        button.add_release_listener(action)
        return button

    def turn_page(self):
        """ Turn book genre page """

        start = (self.current_page - 1) * PAGE_SIZE
        end = self.current_page * PAGE_SIZE
        page = self.genres_list[start:end]
        self.genres_dict = self.factory.create_book_genre_items(
            page, self.base_url)
        self.genre_menu.set_items(self.genres_dict, 0, self.go_book_by_genre,
                                  False)
        self.genre_menu.align_content(ALIGN_LEFT)

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

        self.genre_menu.clean_draw_update()

        self.left_button.change_label(str(self.current_page - 1))
        self.right_button.change_label(
            str(self.total_pages - self.current_page))
        self.set_title(self.current_page)

        if self.genre_menu.get_selected_item() != None:
            self.navigator.unselect()
        else:
            if not self.navigator.is_selected():
                self.back_button.set_selected(True)
                self.back_button.clean_draw_update()

        self.link_borders()

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

        :param event: the event to handle
        """
        self.handle_event_common(event)

    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
        """
        self.navigator.add_observers(update_observer, redraw_observer)
        self.genre_menu.add_menu_observers(update_observer,
                                           redraw_observer,
                                           release=False)