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)
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
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)
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()
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')
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)
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 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 _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
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()
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())
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()
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()
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