Exemple #1
0
 def __init__(self, rect, manager):
     self.text = Message("Welcome to Vibe!").html_text + "<br>"
     self.rect = rect
     self.text_box = None
     self.manager = manager
     super().__init__(self.rect, manager, ["message_log"])
     self.text_box = UITextBox(self.text, self.rect, self.manager, wrap_to_height=False, layer_starting_height=1)
Exemple #2
0
    def add_message(self, message):
        self.text += message.html_text + "<br>"
        if self.text_box:
            self.text_box.kill()
        
        self.text_box = UITextBox(self.text,
            pygame.Rect((0, 0), (self.rect.width, self.rect.height)), self.manager, wrap_to_height=False, layer_starting_height=1, container=self.get_container())
        self.text_box.parse_html_into_style_data()

        """
        got this from Snayff, not quite sure how it works
        sauce: https://bitbucket.org/Snayff/notquiteparadise/src/develop/scripts/engine/ui/elements/message_log.py
        """

        if self.text_box.scroll_bar:
            scroll_bar = self.text_box.scroll_bar
            scroll_bar.scroll_wheel_down = False
            scroll_bar.scroll_position += (250 * 1)
            scroll_bar.scroll_position = min(scroll_bar.scroll_position,
                                           scroll_bar.bottom_limit - scroll_bar.sliding_button.rect.height)
            x_pos = scroll_bar.rect.x + scroll_bar.shadow_width + scroll_bar.border_width
            y_pos = scroll_bar.scroll_position + scroll_bar.rect.y + scroll_bar.shadow_width + \
                    scroll_bar.border_width + scroll_bar.button_height
            scroll_bar.sliding_button.set_position(pygame.math.Vector2(x_pos, y_pos))

            scroll_bar.start_percentage = scroll_bar.scroll_position / scroll_bar.scrollable_height
            if not scroll_bar.has_moved_recently:
                scroll_bar.has_moved_recently = True
Exemple #3
0
    def __init__(
        self,
        size: tuple[int, int],
        manager: IUIManagerInterface,
        udp: UDP_P2P,
        username: str,
    ) -> None:
        # region Docstring
        """
        Creates a `Chat` object

        ### Arguments
            `size {(int, int)}`:
                `summary`: the size of the chat window
            `manager {UIManager}`:
                `summary`: the UIManager that manages this element.
            `udp {UDP_P2P}`:
                `summary`: the udp object
            `username {str}`:
                `summary`: the username of this host
        """
        # endregion
        super().__init__(relative_rect=Rect((Game.SIZE[0], 0), size),
                         manager=manager)

        # region Element creation

        self.textbox = UITextBox(
            html_text="",
            relative_rect=Rect((0, 0), (size[0], size[1] - 25)),
            manager=manager,
            container=self,
        )

        self.entryline = UITextEntryLine(
            relative_rect=Rect((0, size[1] - 28), (size[0] - 50, 20)),
            manager=manager,
            container=self,
        )
        self.entryline.set_text_length_limit(100)

        self.enterbtn = UIButton(
            text="Enter",
            relative_rect=Rect((size[0] - 50, size[1] - 28), (50, 30)),
            manager=manager,
            container=self,
        )

        # endregion

        self.record = ""
        self.size = size
        self.udp = udp
        self.username = username
    def open_new_page(self, page_link: str):
        self.page_display.kill()
        self.page_display = None
        if page_link in self.pages:
            text = self.pages[page_link]

            self.page_display = UITextBox(text,
                                          pygame.Rect((0,
                                                       self.page_y_start_pos),
                                                      self.remaining_window_size),
                                          manager=self.ui_manager,
                                          container=self,
                                          parent_element=self)
Exemple #5
0
    def __init__(self,
                 rect: pygame.Rect,
                 html_message: str,
                 manager: IUIManagerInterface,
                 *,
                 window_title: str = 'Message',
                 object_id: str = '#message_window'):

        super().__init__(rect,
                         manager,
                         window_display_title=window_title,
                         object_id=object_id,
                         resizable=True)

        minimum_dimensions = (250, 160)
        if rect.width < minimum_dimensions[
                0] or rect.height < minimum_dimensions[1]:
            warn_string = ("Initial size: " + str(rect.size) +
                           " is less than minimum dimensions: " +
                           str(minimum_dimensions))
            warnings.warn(warn_string, UserWarning)
        self.set_minimum_dimensions(minimum_dimensions)

        self.dismiss_button = None
        self.text_block = None

        button_size = (70, 20)
        button_spacing = 10
        button_vertical_space = (button_spacing * 2) + button_size[1]

        dismiss_button_rect = pygame.Rect((0, 0), button_size)
        dismiss_button_rect.bottomright = (-button_spacing, -button_spacing)
        self.dismiss_button = UIButton(
            relative_rect=dismiss_button_rect,
            text="Dismiss",
            manager=manager,
            container=self,
            tool_tip_text="Click to get rid of this message.",
            object_id='#dismiss_button',
            anchors={
                "left": "right",
                "top": "bottom",
                "right": "right",
                "bottom": "bottom"
            })

        text_block_rect = pygame.Rect(
            0, 0,
            self.get_container().get_size()[0],
            self.get_container().get_size()[1] - button_vertical_space)
        self.text_block = UITextBox(html_message,
                                    text_block_rect,
                                    manager=manager,
                                    container=self,
                                    anchors={
                                        "left": "left",
                                        "top": "top",
                                        "right": "right",
                                        "bottom": "bottom"
                                    })
    def _build_textbox(self):
        new_element = UITextBox(relative_rect=self.bounds,
                                manager=self.manager,
                                html_text=self.html,
                                wrap_to_height=self._wrap_to_height)

        if self._shape is not None:
            new_element.shape = self._shape
        if self._shape_corner_radius is not None:
            new_element.shape_corner_radius = self._shape_corner_radius

        if self.element is not None:
            self.kill()
        self.element = new_element
        self.background_color = self._background_color
        self.scroll_to_bottom()
Exemple #7
0
    def __init__(self):

        self.manager = UIManager((800, 600), 'themes/home.json')

        self.title = UILabel(relative_rect=pygame.Rect(400 - 100, 20, 200, 50),
                             text='Instruction',
                             manager=self.manager,
                             object_id='#title')

        self.text = UITextBox(
            relative_rect=pygame.Rect(100, 100, 800 - 200, 600 - 100),
            html_text=
            "<body><b>Touche</b><br>Espace -> Tirer<br>Entrer -> Magasin<br>Echap -> Menu de sauvegarde<br>Flèche droite et gauche -> Se déplacer<br><br><b>Système de Niveau</b><br>Niveau 1 -> 0 à 5000 points<br>Niveau 2 -> 5000 à 10000 points<br>Niveau 3 -> 10000 à 15000 points<br>Niveau 4 -> plus de 15000 points<br><br><b>Système du jeu</b><br>Le Joueur commence avec 3 vies, lorsque un monstre touche le joueur celui-ci perd une vie et le monstre meurt.<br>Un monstre rapporte 100 points et 1 credit lorsque le joueur le tue et retire 50 points lorsque le monstre touche le sol<br>Le Joueur a un pourcentage de chance d'obtenir un bonus lorsqu'il tue un monstre<br><br><b>Les Bonus</b><br>Double attaque -> Double les dégats du missile du joueur<br>3 missiles -> Tire 3 missiles au lieu de 1<br>Double score -> Double le score du joueur<br>Temps d'apparition -> Le temps d'apparition est augmenté de 2s</body>",
            manager=self.manager)

        self.buttonReturn = UIButton(relative_rect=pygame.Rect(
            20, 20, 200, 50),
                                     text='Retour',
                                     manager=self.manager)

        self.buttonLogout = UIButton(relative_rect=pygame.Rect(
            800 - 220, 20, 200, 50),
                                     text='Déconnexion',
                                     manager=self.manager,
                                     object_id='#button-logout')
Exemple #8
0
    def __init__(self, pos, manager):
        super().__init__(
            pygame.Rect(pos, (400, 200)),
            manager=manager,
            window_display_title="speaknspell",
            object_id="#speaknspell",
            resizable=True,
        )

        self.box = UITextBox(
            "",
            relative_rect=pygame.Rect(0, 0, 368, 100),
            manager=manager,
            container=self,
            anchors={
                "left": "left",
                "right": "right",
                "top": "top",
                "bottom": "bottom",
            },
        )

        self.input = UITextEntryLine(
            relative_rect=pygame.Rect(0, -35, 368, 30),
            manager=manager,
            container=self,
            anchors={
                "left": "left",
                "right": "right",
                "top": "bottom",
                "bottom": "bottom",
            },
        )

        self.engine = pyttsx3.init()
        self.engine.setProperty("rate", 150)
        self.speakthrd = None

        self.speak("Hello, thank you for using snakeware!")
        self.input.focus()

        # history attributes
        self.histsize = 100
        self.histindex = -1
        self.history = ["Hello, thank you for using snakeware!"]
        self.cached_command = ""
    def __init__(self, rect: pygame.Rect,
                 manager: IUIManagerInterface,
                 action_long_desc: str,
                 *,
                 window_title: str = 'Confirm',
                 action_short_name: str = 'OK',
                 blocking: bool = True,
                 object_id: Union[ObjectID, str] = ObjectID('#confirmation_dialog', None),
                 visible: int = 1):

        super().__init__(rect, manager,
                         window_display_title=window_title,
                         object_id=object_id,
                         resizable=True,
                         visible=visible)

        minimum_dimensions = (260, 200)
        if rect.width < minimum_dimensions[0] or rect.height < minimum_dimensions[1]:
            warn_string = ("Initial size: " + str(rect.size) +
                           " is less than minimum dimensions: " + str(minimum_dimensions))
            warnings.warn(warn_string, UserWarning)
        self.set_minimum_dimensions(minimum_dimensions)

        self.confirm_button = UIButton(relative_rect=pygame.Rect(-220, -40, 100, 30),
                                       text=action_short_name,
                                       manager=self.ui_manager,
                                       container=self,
                                       object_id='#confirm_button',
                                       anchors={'left': 'right',
                                                'right': 'right',
                                                'top': 'bottom',
                                                'bottom': 'bottom'})

        self.cancel_button = UIButton(relative_rect=pygame.Rect(-110, -40, 100, 30),
                                      text='Cancel',
                                      manager=self.ui_manager,
                                      container=self,
                                      object_id='#cancel_button',
                                      anchors={'left': 'right',
                                               'right': 'right',
                                               'top': 'bottom',
                                               'bottom': 'bottom'})

        text_width = self.get_container().get_size()[0] - 10
        text_height = self.get_container().get_size()[1] - 50
        self.confirmation_text = UITextBox(html_text=action_long_desc,
                                           relative_rect=pygame.Rect(5, 5,
                                                                     text_width,
                                                                     text_height),
                                           manager=self.ui_manager,
                                           container=self,
                                           anchors={'left': 'left',
                                                    'right': 'right',
                                                    'top': 'top',
                                                    'bottom': 'bottom'})

        self.set_blocking(blocking)
Exemple #10
0
    def __addmsg(self, msg: str) -> None:
        # region Docstring
        """
        Method to insert text in the `UITextBox` element

        ### Arguments
            `msg {str}`:
                `summary`: the text to insert
        """
        # endregion
        self.record += msg
        self.textbox.kill()
        self.textbox = UITextBox(
            html_text=self.record,
            relative_rect=Rect((0, 0), (self.size[0], self.size[1] - 25)),
            container=self,
            manager=self.ui_manager,
        )
Exemple #11
0
    def update(self, time_delta: float) -> None:
        # region Docstring
        """
        Overridden method to update the element

        ### Arguments
            `time_delta {float}`:
                `summary`: the time passed between frames, measured in seconds.
        """
        # endregion

        super().update(time_delta)
        if self.record != self.textbox.html_text:
            self.textbox.kill()
            self.textbox = UITextBox(
                html_text=self.record,
                relative_rect=Rect((0, 0), (self.size[0], self.size[1] - 25)),
                container=self,
                manager=self.ui_manager,
            )
Exemple #12
0
    def _create_section(self, title: str, items: Enum, y_offset) -> int:
        item_height = 35

        label_rect = pygame.Rect((0, y_offset), (LogBookPanel.PANEL_WIDTH, item_height))
        label_text = "<strong>" + title + "</strong>"
        title_label = UITextBox(label_text, label_rect, self.manager, container=self.panel)
    
        y_offset += item_height

        item_label_width = LogBookPanel.PANEL_WIDTH - 30

        for item in items:
            img_rect = pygame.Rect((5, y_offset + 6), (24, 24))
            checkbox_img = UIImage(img_rect, LogBookPanel.UNCHECKED_IMG, self.manager, container=self.panel)

            label_rect = pygame.Rect((30, y_offset), (item_label_width, item_height))
            item_button = UITextBox(item.pretty(), label_rect, self.manager, container=self.panel)

            self._checkboxes[checkbox_img] = False

            y_offset += item_height

        return y_offset
Exemple #13
0
    def recreate_ui(self):
        self.ui_manager.set_window_resolution(self.options.resolution)
        self.ui_manager.clear_and_reset()

        self.background_surface = pygame.Surface(self.options.resolution)

        if self.start_up == True:
            self.image = UIImage(pygame.Rect((0, 0), self.options.resolution), title_screen_image, self.ui_manager)
        elif self.enter_mines == True:
            self.image = UIImage(pygame.Rect((0, 0), self.options.resolution), mines_image, self.ui_manager)
        elif self.enter_busstop == True:
            self.image = UIImage(pygame.Rect((0, 0), self.options.resolution), busstop_image, self.ui_manager)
        elif self.enter_uptown == True:
            self.image = UIImage(pygame.Rect((0, 0), self.options.resolution), uptown_image, self.ui_manager)
        else: 
            self.background_surface.fill(self.ui_manager.get_theme().get_colour('dark_bg'))
            self.background_surface.blit(pygame.image.load("media/images/background.png"), (0, 0))
            
            global response_history
            response = response_history
            response_history = response
            self.text_entry = UITextEntryLine(pygame.Rect((50, 550), (700, 50)), self.ui_manager, object_id = "#text_entry")
            self.text_block = UITextBox(response, pygame.Rect((50, 25), (700, 500)), self.ui_manager, object_id = "#text_block")
Exemple #14
0
    def process_events(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                self.running = False

            self.ui_manager.process_events(event)            

            if event.type==pygame.KEYDOWN:
                if event.key== pygame.K_UP:              
                    if self.start_up == True:
                        self.start_up = False
                        self.recreate_ui()
                    if self.enter_mines == True:
                        self.enter_mines = False
                        self.recreate_ui()
                    if self.enter_busstop == True:
                        self.enter_busstop = False
                        self.recreate_ui()
                    if self.enter_uptown == True:
                        self.enter_uptown = False
                        self.recreate_ui()
            if event.type == pygame.USEREVENT:
                if (event.user_type == pygame_gui.UI_TEXT_ENTRY_FINISHED and event.ui_object_id == '#text_entry'):
                    if event.text != "":
                        # Turn the user's input into a string.
                        message = event.text

                        # Begin the response message. Start with repeating the user's input.
                        response = "<b><i>> {message}</i></b>".format(message = message)

                        # Create a player object using the player's save data.
                        player_data = player.Player()

                        # Check to see if the player is in a scripted sequence.
                        if player_data.scene is not None: # If they are...
                            if player_data.scene == config.scene_id_newgame: # If the player has started the game for the first time.
                                command_response = scenes.Introduction(message)
                                response += ("<br>" * 4) + command_response
                        else: # If they aren't...
                            command_response = utilities.parse_message(message)
                            response += ("<br>" * 4) + command_response

                        # End the response with some decoration. ^_^
                        response += ("<br>" * 4) + ("-" * 20) + ("<br>" * 4)

                        # Add this response to our response history, and then send the entire history to be rendered.
                        global response_history
                        response += response_history
                        response_history = response
                        # Render the response.
                        self.text_entry.set_text("")
                        self.text_block.kill()
                        self.text_block = UITextBox(response, pygame.Rect((50, 25), (700, 500)), self.ui_manager, object_id = "#text_block")
                        
                        if command_response == "You enter the Mines.":
                            self.enter_mines = True
                            self.recreate_ui()
                        if command_response == "You enter a Bus Stop.":
                            self.enter_busstop = True
                            self.recreate_ui()
                        if command_response == "You enter Uptown.":
                            self.enter_uptown = True
                            self.recreate_ui()
Exemple #15
0
class Chat(UIContainer):
    # region Docstring
    """
    Class to display the game chat
    """

    # endregion

    def __init__(
        self,
        size: tuple[int, int],
        manager: IUIManagerInterface,
        udp: UDP_P2P,
        username: str,
    ) -> None:
        # region Docstring
        """
        Creates a `Chat` object

        ### Arguments
            `size {(int, int)}`:
                `summary`: the size of the chat window
            `manager {UIManager}`:
                `summary`: the UIManager that manages this element.
            `udp {UDP_P2P}`:
                `summary`: the udp object
            `username {str}`:
                `summary`: the username of this host
        """
        # endregion
        super().__init__(relative_rect=Rect((Game.SIZE[0], 0), size),
                         manager=manager)

        # region Element creation

        self.textbox = UITextBox(
            html_text="",
            relative_rect=Rect((0, 0), (size[0], size[1] - 25)),
            manager=manager,
            container=self,
        )

        self.entryline = UITextEntryLine(
            relative_rect=Rect((0, size[1] - 28), (size[0] - 50, 20)),
            manager=manager,
            container=self,
        )
        self.entryline.set_text_length_limit(100)

        self.enterbtn = UIButton(
            text="Enter",
            relative_rect=Rect((size[0] - 50, size[1] - 28), (50, 30)),
            manager=manager,
            container=self,
        )

        # endregion

        self.record = ""
        self.size = size
        self.udp = udp
        self.username = username

    def process_event(self, event: Event) -> Union[bool, None]:
        # region Docstring
        """
        Overridden method to handle the gui events

        ### Arguments
            `event {Event}`:
                `summary`: the fired event

        ### Returns
            `bool | None`: return if the event has been handled
        """
        # endregion

        handled = super().process_event(event)
        if event.type != USEREVENT:
            return

        if (event.user_type == UI_TEXT_ENTRY_FINISHED and event.ui_element
                == self.entryline) or (event.user_type == UI_BUTTON_PRESSED
                                       and event.ui_element == self.enterbtn):
            self.__send()
            handled = True

        return handled

    def __send(self) -> None:
        # region Docstring
        """
        Handles the press of the enter `UIButton`, sending the user message.\n
        """
        # endregion

        if len(self.entryline.get_text().strip()) > 0:
            self.udp.transmission("CHA", "01", self.username,
                                  self.entryline.get_text().strip())
            self.__addmsg(
                f"<b>(YOU): </b><br>{self.entryline.get_text().strip()}<br>")
            self.entryline.set_text("")

    def receive(self, data: Packet, addr: Tuple[str, int],
                time: datetime) -> None:
        # region Docstring
        """
        Method that handles the received data, address and time of reception

        ### Arguments
            `data {Packet}`:
                `summary`: the data received
            `addr {Tuple[str, int]}`:
                `summary`: the source address and port
                example: (192.168.0.1, 6000)
            `time {datetime}`:
                `summary`: the time of the packet reception
        """
        # endregion

        n = UDP_P2P.latency(
            datetime.strptime(time.strftime("%H%M%S%f"), "%H%M%S%f"),
            datetime.strptime(data.time + "000", "%H%M%S%f"),
        )

        self.record += f"<b>({data.nick.strip()} - {addr[0]} - {n}ms): </b><br>{data.msg.strip()}<br>"

    def update(self, time_delta: float) -> None:
        # region Docstring
        """
        Overridden method to update the element

        ### Arguments
            `time_delta {float}`:
                `summary`: the time passed between frames, measured in seconds.
        """
        # endregion

        super().update(time_delta)
        if self.record != self.textbox.html_text:
            self.textbox.kill()
            self.textbox = UITextBox(
                html_text=self.record,
                relative_rect=Rect((0, 0), (self.size[0], self.size[1] - 25)),
                container=self,
                manager=self.ui_manager,
            )

    def __addmsg(self, msg: str) -> None:
        # region Docstring
        """
        Method to insert text in the `UITextBox` element

        ### Arguments
            `msg {str}`:
                `summary`: the text to insert
        """
        # endregion
        self.record += msg
        self.textbox.kill()
        self.textbox = UITextBox(
            html_text=self.record,
            relative_rect=Rect((0, 0), (self.size[0], self.size[1] - 25)),
            container=self,
            manager=self.ui_manager,
        )
    def __init__(self,
                 rect: pygame.Rect,
                 manager: IUIManagerInterface,
                 window_title: str = 'pygame-gui.console_title_bar',
                 object_id: Union[ObjectID,
                                  str] = ObjectID('#console_window', None),
                 visible: int = 1,
                 preload_bold_log_font: bool = True):
        super().__init__(rect,
                         manager,
                         window_display_title=window_title,
                         object_id=object_id,
                         resizable=True,
                         visible=visible)

        self.default_log_prefix = '> '
        self.log_prefix = self.default_log_prefix

        self.should_logged_commands_escape_html = True

        self.logged_commands_above = []
        self.current_logged_command = None
        self.logged_commands_below = []

        self.command_entry = UITextEntryLine(relative_rect=pygame.rect.Rect(
            (2, -32), (self.get_container().get_size()[0] - 4, 30)),
                                             manager=self.ui_manager,
                                             container=self,
                                             object_id='#command_entry',
                                             anchors={
                                                 'left': 'left',
                                                 'right': 'right',
                                                 'top': 'bottom',
                                                 'bottom': 'bottom'
                                             })

        self.log = UITextBox(html_text="",
                             relative_rect=pygame.rect.Rect(
                                 (2, 2),
                                 (self.get_container().get_size()[0] - 4,
                                  self.get_container().get_size()[1] - 36)),
                             manager=manager,
                             container=self,
                             object_id='#log',
                             anchors={
                                 'left': 'left',
                                 'right': 'right',
                                 'top': 'top',
                                 'bottom': 'bottom'
                             })

        if preload_bold_log_font:
            # Would be better to load this font during UIManager setup, but this is probably
            # second best place. We can't know if someone will use the console window in advance
            # but if they do and use the default bold output setup for it, it would be a good idea
            # to load the bold font at th the same time th other UI stuff is loaded.

            log_font_info = self.ui_theme.get_font_info(
                self.log.combined_element_ids)
            font_dict = self.ui_manager.get_theme().get_font_dictionary()
            bold_font_id = font_dict.create_font_id(log_font_info['size'],
                                                    log_font_info['name'],
                                                    bold=True,
                                                    italic=False)
            if not font_dict.check_font_preloaded(bold_font_id):
                font_dict.preload_font(log_font_info['size'],
                                       log_font_info['name'],
                                       bold=True)
class UIConsoleWindow(UIWindow):
    """
    Create a basic console window. By default it doesn't do anything except log
    commands entered into the console in the text box log. There is an event
    and a few methods however that allow you to hook this console window up
    to do whatever you would like with the entered text commands.

    See the pygame GUI examples repository for an example using it to run the
    Python Interactive Shell.

    :param rect: A rect determining the size and position of the console window.
    :param manager: The UI manager.
    :param window_title: The title displayed in the windows title bar.
    :param object_id: The object ID for the window, used for theming - defaults to
                      '#console_window'
    :param visible: Whether the element is visible by default.
    """
    def __init__(self,
                 rect: pygame.Rect,
                 manager: IUIManagerInterface,
                 window_title: str = 'pygame-gui.console_title_bar',
                 object_id: Union[ObjectID,
                                  str] = ObjectID('#console_window', None),
                 visible: int = 1,
                 preload_bold_log_font: bool = True):
        super().__init__(rect,
                         manager,
                         window_display_title=window_title,
                         object_id=object_id,
                         resizable=True,
                         visible=visible)

        self.default_log_prefix = '> '
        self.log_prefix = self.default_log_prefix

        self.should_logged_commands_escape_html = True

        self.logged_commands_above = []
        self.current_logged_command = None
        self.logged_commands_below = []

        self.command_entry = UITextEntryLine(relative_rect=pygame.rect.Rect(
            (2, -32), (self.get_container().get_size()[0] - 4, 30)),
                                             manager=self.ui_manager,
                                             container=self,
                                             object_id='#command_entry',
                                             anchors={
                                                 'left': 'left',
                                                 'right': 'right',
                                                 'top': 'bottom',
                                                 'bottom': 'bottom'
                                             })

        self.log = UITextBox(html_text="",
                             relative_rect=pygame.rect.Rect(
                                 (2, 2),
                                 (self.get_container().get_size()[0] - 4,
                                  self.get_container().get_size()[1] - 36)),
                             manager=manager,
                             container=self,
                             object_id='#log',
                             anchors={
                                 'left': 'left',
                                 'right': 'right',
                                 'top': 'top',
                                 'bottom': 'bottom'
                             })

        if preload_bold_log_font:
            # Would be better to load this font during UIManager setup, but this is probably
            # second best place. We can't know if someone will use the console window in advance
            # but if they do and use the default bold output setup for it, it would be a good idea
            # to load the bold font at th the same time th other UI stuff is loaded.

            log_font_info = self.ui_theme.get_font_info(
                self.log.combined_element_ids)
            font_dict = self.ui_manager.get_theme().get_font_dictionary()
            bold_font_id = font_dict.create_font_id(log_font_info['size'],
                                                    log_font_info['name'],
                                                    bold=True,
                                                    italic=False)
            if not font_dict.check_font_preloaded(bold_font_id):
                font_dict.preload_font(log_font_info['size'],
                                       log_font_info['name'],
                                       bold=True)

    def set_log_prefix(self, prefix: str) -> None:
        """
        Set the prefix to add before commands when they are displayed in the log.
        This defaults to '> '.

        :param prefix: A string that is prepended to commands before they are added to the
                       log text box.
        """
        self.log_prefix = prefix

    def restore_default_prefix(self) -> None:
        """
        Restore the console log prefix to it's default value (which is: '> ')
        """
        self.log_prefix = self.default_log_prefix

    def set_logged_commands_escape_html(self, should_escape: bool) -> None:
        """
        Sets whether commands should have any HTML characters escaped before being added
        to the log. This is because the log uses an HTML Text box and most of the time we don't
        want to assume that every entered > or < is part of an HTML tag.

        By default HTML is escaped for commands added to the log.

        :param should_escape: A bool to switch escaping HTML on commands on or off.
        """
        self.should_logged_commands_escape_html = should_escape

    def add_output_line_to_log(self,
                               text_to_add: str,
                               is_bold: bool = True,
                               remove_line_break: bool = False,
                               escape_html: bool = True) -> None:
        """
        Adds a single line of text to the log text box. This is intended as a hook to add
        output/responses to commands entered into the console.

        :param text_to_add: The single line of text to add to the log.
        :param is_bold: Determines whether the output is shown in bold or not. Defaults to True.
        :param remove_line_break: Set this to True to remove the automatic line break at the end
                                  of the line of text. Sometimes you might want to add some output
                                  all on a single line (e.g. a console style 'progress bar')
        :param escape_html:  Determines whether to escape any HTML in this line of text. Defaults
                             to True, as most people won't be expecting every > or < to be
                             processed as HTML.
        """
        output_to_log = html.escape(
            text_to_add) if escape_html else text_to_add
        line_ending = '' if remove_line_break else '<br>'
        if is_bold:
            self.log.append_html_text('<b>' + output_to_log + '</b>' +
                                      line_ending)
        else:
            self.log.append_html_text(output_to_log + line_ending)

    def process_event(self, event: pygame.event.Event) -> bool:
        """
        See if we need to handle an event passed down by the UI manager.
        Returns True if the console window dealt with this event.

        :param event: The event to handle
        """
        handled = super().process_event(event)

        if (self.command_entry.is_focused and event.type == pygame.KEYDOWN):
            if event.key == pygame.K_DOWN:
                if len(self.logged_commands_below) > 0:
                    popped_command = self.logged_commands_below.pop()
                    if self.current_logged_command is not None:
                        self.logged_commands_above.append(
                            self.current_logged_command)
                    self.current_logged_command = popped_command
                    self.command_entry.set_text(self.current_logged_command)
            elif event.key == pygame.K_UP:
                if len(self.logged_commands_above) > 0:
                    popped_command = self.logged_commands_above.pop()
                    if self.current_logged_command is not None:
                        self.logged_commands_below.append(
                            self.current_logged_command)
                    self.current_logged_command = popped_command
                    self.command_entry.set_text(self.current_logged_command)

        if event.type == UI_TEXT_ENTRY_FINISHED and event.ui_element == self.command_entry:
            handled = True
            command = self.command_entry.get_text()
            command_for_log = command
            self._restore_command_log_to_end()
            self.logged_commands_above.append(command_for_log)
            if self.should_logged_commands_escape_html:
                command_for_log = html.escape(command_for_log)
            self.log.append_html_text(self.log_prefix + command_for_log +
                                      "<br>")
            self.command_entry.set_text("")

            event_data = {
                'command': command,
                'ui_element': self,
                'ui_object_id': self.most_specific_combined_id
            }
            command_entered_event = pygame.event.Event(
                UI_CONSOLE_COMMAND_ENTERED, event_data)
            pygame.event.post(command_entered_event)

        if event.type == UI_TEXT_ENTRY_CHANGED and event.ui_element == self.command_entry:
            self._restore_command_log_to_end()

        return handled

    def _restore_command_log_to_end(self):
        if self.current_logged_command is not None:
            self.logged_commands_above.append(self.current_logged_command)
        self.current_logged_command = None
        while len(self.logged_commands_below) > 0:
            self.logged_commands_above.append(self.logged_commands_below.pop())
Exemple #18
0
class SpeakSpell(pygame_gui.elements.UIWindow):
    speakthrd = None

    def __init__(self, pos, manager):
        super().__init__(
            pygame.Rect(pos, (400, 200)),
            manager=manager,
            window_display_title="speaknspell",
            object_id="#speaknspell",
            resizable=True,
        )

        self.box = UITextBox(
            "",
            relative_rect=pygame.Rect(0, 0, 368, 100),
            manager=manager,
            container=self,
            anchors={
                "left": "left",
                "right": "right",
                "top": "top",
                "bottom": "bottom",
            },
        )

        self.input = UITextEntryLine(
            relative_rect=pygame.Rect(0, -35, 368, 30),
            manager=manager,
            container=self,
            anchors={
                "left": "left",
                "right": "right",
                "top": "bottom",
                "bottom": "bottom",
            },
        )

        self.engine = pyttsx3.init()
        self.engine.setProperty("rate", 150)
        self.speakthrd = None

        self.speak("Hello, thank you for using snakeware!")
        self.input.focus()

        # history attributes
        self.histsize = 100
        self.histindex = -1
        self.history = ["Hello, thank you for using snakeware!"]
        self.cached_command = ""

    def speak(self, text):
        if self.speakthrd is not None and self.speakthrd.is_alive():
            return

        if text == "":
            return

        text = re.sub(r"(\\r)?\\n", "<br>", text)
        spoken = re.sub(r"<(.*?)>", "", text)
        self.engine.say(spoken)
        self.speakthrd = threading.Thread(target=self.engine.runAndWait,
                                          args=())
        self.speakthrd.start()
        self.box.html_text = text
        self.box.rebuild()
        self.input.set_text("")

    def cache_command(self):
        self.cached_command = self.input.get_text()

    def flush_command_cache(self):
        self.cached_command = ""

    def set_histindex(self, increment):
        try:
            # self.history[self.histindex + increment]
            self.histindex += increment
        except IndexError:
            pass
        return self.histindex

    def set_from_history(self):
        if self.histindex > -1:
            self.input.set_text(self.history[self.histindex])
        else:
            self.input.set_text(self.cached_command)
        self.input.edit_position = len(self.input.get_text())

    def add_to_history(self, text):
        self.history = [text] + self.history
        if len(self.history) > self.histsize:
            del self.history[-1]

    def process_event(self, event):
        super().process_event(event)
        if event.type == pygame.USEREVENT and event.ui_element == self.input:
            if event.user_type == pygame_gui.UI_TEXT_ENTRY_FINISHED:
                text = self.input.get_text()
                self.add_to_history(text)
                self.histindex = -1
                self.flush_command_cache()
                self.speak(text)
        elif event.type == pygame.KEYUP and event.key in (pygame.K_UP,
                                                          pygame.K_DOWN):
            increment = 1 if event.key == pygame.K_UP else -1
            if self.histindex == -1:
                self.cache_command()
            self.set_histindex(increment)
            self.set_from_history()
Exemple #19
0
class Game:
    def __init__(self):
        # Start up Pygame.
        pygame.init()

        # Title the window our game runs in.
        pygame.display.set_caption(config.game_name)
        
        self.options = Options()

        # Define the dimensions of our game's window.
        self.window_surface = pygame.display.set_mode(self.options.resolution)
        self.window_surface.blit(pygame.image.load("media/images/background.png"), (0, 0))

        self.start_up = True
        self.enter_mines = False
        self.enter_busstop = False
        self.enter_uptown = False

        self.background_surface = None

        self.ui_manager = UIManager(self.options.resolution, PackageResource(package='media.themes', resource='theme.json'))

        self.text_block = None
        self.text_entry = None

        self.message_window = None

        self.recreate_ui()

        self.clock = pygame.time.Clock()
        self.time_delta_stack = deque([])
        self.running = True

    def recreate_ui(self):
        self.ui_manager.set_window_resolution(self.options.resolution)
        self.ui_manager.clear_and_reset()

        self.background_surface = pygame.Surface(self.options.resolution)

        if self.start_up == True:
            self.image = UIImage(pygame.Rect((0, 0), self.options.resolution), title_screen_image, self.ui_manager)
        elif self.enter_mines == True:
            self.image = UIImage(pygame.Rect((0, 0), self.options.resolution), mines_image, self.ui_manager)
        elif self.enter_busstop == True:
            self.image = UIImage(pygame.Rect((0, 0), self.options.resolution), busstop_image, self.ui_manager)
        elif self.enter_uptown == True:
            self.image = UIImage(pygame.Rect((0, 0), self.options.resolution), uptown_image, self.ui_manager)
        else: 
            self.background_surface.fill(self.ui_manager.get_theme().get_colour('dark_bg'))
            self.background_surface.blit(pygame.image.load("media/images/background.png"), (0, 0))
            
            global response_history
            response = response_history
            response_history = response
            self.text_entry = UITextEntryLine(pygame.Rect((50, 550), (700, 50)), self.ui_manager, object_id = "#text_entry")
            self.text_block = UITextBox(response, pygame.Rect((50, 25), (700, 500)), self.ui_manager, object_id = "#text_block")

    def process_events(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                self.running = False

            self.ui_manager.process_events(event)            

            if event.type==pygame.KEYDOWN:
                if event.key== pygame.K_UP:              
                    if self.start_up == True:
                        self.start_up = False
                        self.recreate_ui()
                    if self.enter_mines == True:
                        self.enter_mines = False
                        self.recreate_ui()
                    if self.enter_busstop == True:
                        self.enter_busstop = False
                        self.recreate_ui()
                    if self.enter_uptown == True:
                        self.enter_uptown = False
                        self.recreate_ui()
            if event.type == pygame.USEREVENT:
                if (event.user_type == pygame_gui.UI_TEXT_ENTRY_FINISHED and event.ui_object_id == '#text_entry'):
                    if event.text != "":
                        # Turn the user's input into a string.
                        message = event.text

                        # Begin the response message. Start with repeating the user's input.
                        response = "<b><i>> {message}</i></b>".format(message = message)

                        # Create a player object using the player's save data.
                        player_data = player.Player()

                        # Check to see if the player is in a scripted sequence.
                        if player_data.scene is not None: # If they are...
                            if player_data.scene == config.scene_id_newgame: # If the player has started the game for the first time.
                                command_response = scenes.Introduction(message)
                                response += ("<br>" * 4) + command_response
                        else: # If they aren't...
                            command_response = utilities.parse_message(message)
                            response += ("<br>" * 4) + command_response

                        # End the response with some decoration. ^_^
                        response += ("<br>" * 4) + ("-" * 20) + ("<br>" * 4)

                        # Add this response to our response history, and then send the entire history to be rendered.
                        global response_history
                        response += response_history
                        response_history = response
                        # Render the response.
                        self.text_entry.set_text("")
                        self.text_block.kill()
                        self.text_block = UITextBox(response, pygame.Rect((50, 25), (700, 500)), self.ui_manager, object_id = "#text_block")
                        
                        if command_response == "You enter the Mines.":
                            self.enter_mines = True
                            self.recreate_ui()
                        if command_response == "You enter a Bus Stop.":
                            self.enter_busstop = True
                            self.recreate_ui()
                        if command_response == "You enter Uptown.":
                            self.enter_uptown = True
                            self.recreate_ui()
    def run(self):
        while self.running:
            time_delta = self.clock.tick() / 1000
            
            # Check for inputs from the player.
            self.process_events()

            # Respond to inputs.
            self.ui_manager.update(time_delta)

            # Draw the graphics.
            self.window_surface.blit(self.background_surface, (0, 0))
            self.ui_manager.draw_ui(self.window_surface)

            pygame.display.update()
Exemple #20
0
class SpeakSpell(pygame_gui.elements.UIWindow):
    speakthrd = None

    def __init__(self, pos, manager):
        super().__init__(
            pygame.Rect(pos, (400, 200)),
            manager=manager,
            window_display_title="speaknspell",
            object_id="#speaknspell",
            resizable=True,
        )

        self.box = UITextBox(
            "",
            relative_rect=pygame.Rect(0, 0, 368, 100),
            manager=manager,
            container=self,
            anchors={
                "left": "left",
                "right": "right",
                "top": "top",
                "bottom": "bottom",
            },
        )

        self.input = UITextEntryLine(
            relative_rect=pygame.Rect(0, -35, 368, 30),
            manager=manager,
            container=self,
            anchors={
                "left": "left",
                "right": "right",
                "top": "bottom",
                "bottom": "bottom",
            },
        )

        self.engine = pyttsx3.init()
        self.engine.setProperty("rate", 150)
        self.speakthrd = None

        self.speak("Hello, thank you for using snakeware!")
        self.input.focus()

    def speak(self, text):
        if self.speakthrd is not None and self.speakthrd.is_alive():
            return

        if text == "":
            return

        text = text.replace("\n", "<br>")

        spoken = re.sub(r"<(.*?)>", "", text)
        self.engine.say(spoken)
        self.speakthrd = threading.Thread(target=self.engine.runAndWait, args=())
        self.speakthrd.start()
        self.box.html_text = text
        self.box.rebuild()
        self.input.set_text("")

    def process_event(self, event):
        super().process_event(event)
        if event.type == pygame.USEREVENT and event.ui_element == self.input:
            if event.user_type == pygame_gui.UI_TEXT_ENTRY_FINISHED:
                self.speak(self.input.get_text())
    def __init__(self, manager):
        super().__init__(pygame.Rect((200, 50), (420, 520)),
                         manager,
                         window_display_title='GUIopedia!',
                         object_id="#guiopedia_window")

        search_bar_top_margin = 2
        search_bar_bottom_margin = 2
        self.search_box = pygame_gui.elements.UITextEntryLine(pygame.Rect((150,
                                                                           search_bar_top_margin),
                                                                          (240, 20)),
                                                              manager=manager,
                                                              container=self,
                                                              parent_element=self)

        self.search_label = pygame_gui.elements.UILabel(pygame.Rect((90,
                                                                     search_bar_top_margin),
                                                                    (56,
                                                                     self.search_box.rect.height)),
                                                        "Search:",
                                                        manager=manager,
                                                        container=self,
                                                        parent_element=self)

        self.home_button = pygame_gui.elements.UIButton(pygame.Rect((20, search_bar_top_margin),
                                                                    (29, 29)),
                                                        '',
                                                        manager=manager,
                                                        container=self,
                                                        parent_element=self,
                                                        object_id='#home_button')

        self.remaining_window_size = (self.get_container().get_size()[0],
                                      (self.get_container().get_size()[1] -
                                       (self.search_box.rect.height +
                                        search_bar_top_margin +
                                        search_bar_bottom_margin)))

        self.pages = {}
        page_path = 'data/guiopedia/'
        file_paths = [join(page_path, f) for f in listdir(page_path) if isfile(join(page_path, f))]
        for file_path in file_paths:
            with open(file_path, 'r') as page_file:
                file_id = splitext(basename(file_path))[0]
                file_data = ""
                for line in page_file:
                    line = line.rstrip(linesep).lstrip()
                    # kind of hacky way to add back spaces at the end of new lines that
                    # are removed by the pyCharm HTML
                    # editor. perhaps our HTML parser needs to handle this case
                    # (turning new lines into spaces
                    # but removing spaces at the start of rendered lines?)
                    if len(line) > 0:
                        if line[-1] != '>':
                            line += ' '
                        file_data += line
                self.pages[file_id] = file_data

        index_page = self.pages['index']
        self.page_y_start_pos = (self.search_box.rect.height +
                                 search_bar_top_margin +
                                 search_bar_bottom_margin)
        self.page_display = UITextBox(index_page,
                                      pygame.Rect((0, self.page_y_start_pos),
                                                  self.remaining_window_size),
                                      manager=manager,
                                      container=self,
                                      parent_element=self)
class GUIopediaWindow(pygame_gui.elements.UIWindow):
    def __init__(self, manager):
        super().__init__(pygame.Rect((200, 50), (420, 520)),
                         manager,
                         window_display_title='GUIopedia!',
                         object_id="#guiopedia_window")

        search_bar_top_margin = 2
        search_bar_bottom_margin = 2
        self.search_box = pygame_gui.elements.UITextEntryLine(pygame.Rect((150,
                                                                           search_bar_top_margin),
                                                                          (240, 20)),
                                                              manager=manager,
                                                              container=self,
                                                              parent_element=self)

        self.search_label = pygame_gui.elements.UILabel(pygame.Rect((90,
                                                                     search_bar_top_margin),
                                                                    (56,
                                                                     self.search_box.rect.height)),
                                                        "Search:",
                                                        manager=manager,
                                                        container=self,
                                                        parent_element=self)

        self.home_button = pygame_gui.elements.UIButton(pygame.Rect((20, search_bar_top_margin),
                                                                    (29, 29)),
                                                        '',
                                                        manager=manager,
                                                        container=self,
                                                        parent_element=self,
                                                        object_id='#home_button')

        self.remaining_window_size = (self.get_container().get_size()[0],
                                      (self.get_container().get_size()[1] -
                                       (self.search_box.rect.height +
                                        search_bar_top_margin +
                                        search_bar_bottom_margin)))

        self.pages = {}
        page_path = 'data/guiopedia/'
        file_paths = [join(page_path, f) for f in listdir(page_path) if isfile(join(page_path, f))]
        for file_path in file_paths:
            with open(file_path, 'r') as page_file:
                file_id = splitext(basename(file_path))[0]
                file_data = ""
                for line in page_file:
                    line = line.rstrip(linesep).lstrip()
                    # kind of hacky way to add back spaces at the end of new lines that
                    # are removed by the pyCharm HTML
                    # editor. perhaps our HTML parser needs to handle this case
                    # (turning new lines into spaces
                    # but removing spaces at the start of rendered lines?)
                    if len(line) > 0:
                        if line[-1] != '>':
                            line += ' '
                        file_data += line
                self.pages[file_id] = file_data

        index_page = self.pages['index']
        self.page_y_start_pos = (self.search_box.rect.height +
                                 search_bar_top_margin +
                                 search_bar_bottom_margin)
        self.page_display = UITextBox(index_page,
                                      pygame.Rect((0, self.page_y_start_pos),
                                                  self.remaining_window_size),
                                      manager=manager,
                                      container=self,
                                      parent_element=self)

    def process_event(self, event):
        handled = super().process_event(event)
        if event.type != pygame.USEREVENT:
            return
        if event.user_type == pygame_gui.UI_TEXT_BOX_LINK_CLICKED:
            self.open_new_page(event.link_target)
            handled = True

        if (event.user_type == pygame_gui.UI_TEXT_ENTRY_FINISHED and
                event.ui_element == self.search_box):
            results = self.search_pages(event.text)
            self.create_search_results_page(results)
            self.open_new_page('results')
            handled = True

        if (event.user_type == pygame_gui.UI_BUTTON_PRESSED and
                event.ui_object_id == '#guiopedia_window.#home_button'):
            self.open_new_page('index')
            handled = True

        return handled

    def search_pages(self, search_string: str):
        results = {}
        words = search_string.split()

        for page in self.pages.keys():
            total_occurances_of_search_words = 0
            for word in words:
                word_occurances = self.search_text_for_occurrences_of_word(word, self.pages[page])
                total_occurances_of_search_words += word_occurances
            if total_occurances_of_search_words > 0:
                results[page] = total_occurances_of_search_words

        sorted_results = sorted(results.items(), key=lambda item: item[1], reverse=True)
        return OrderedDict(sorted_results)

    @staticmethod
    def search_text_for_occurrences_of_word(word_to_search_for: str, text_to_search: str) -> int:
        return sum(1 for _ in re.finditer(r'\b%s\b' % re.escape(word_to_search_for),
                                          text_to_search,
                                          flags=re.IGNORECASE))

    def open_new_page(self, page_link: str):
        self.page_display.kill()
        self.page_display = None
        if page_link in self.pages:
            text = self.pages[page_link]

            self.page_display = UITextBox(text,
                                          pygame.Rect((0,
                                                       self.page_y_start_pos),
                                                      self.remaining_window_size),
                                          manager=self.ui_manager,
                                          container=self,
                                          parent_element=self)

    def create_search_results_page(self, results):
        results_text = '<font size=5>Search results</font>'
        if len(results) == 0:
            results_text += '<br><br> No Results Found.'
        else:
            results_text += '<br><br>' + str(len(results)) + ' results found:'
            for result in results.keys():
                results_text += '<br><br> - <a href=\"' + result + '\">' + result + '</a>'

        self.pages['results'] = results_text