Beispiel #1
0
    def __init__(self):

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

        self.title = UILabel(relative_rect=pygame.Rect(400 - 100, 50, 200, 50),
                             text='Inscription',
                             manager=self.manager)

        self.labelPseudo = UILabel(relative_rect=pygame.Rect(400 - 210, 142, 100, 50),
                                   text='Pseudo',
                                   manager=self.manager)

        self.pseudo = UITextEntryLine(relative_rect=pygame.Rect(400 - 100, 150, 200, 50),
                                      manager=self.manager)

        self.labelPassword = UILabel(relative_rect=pygame.Rect(400 - 210, 222, 100, 50),
                                     text='Mot de passe',
                                     manager=self.manager)

        self.password = UITextEntryLine(relative_rect=pygame.Rect(400 - 100, 230, 200, 50),
                                        manager=self.manager)

        self.buttonSignup = UIButton(relative_rect=pygame.Rect(400 - 100, 320, 200, 50),
                                     text="S'inscrire",
                                     manager=self.manager)

        self.buttonLogin = UIButton(relative_rect=pygame.Rect(400 - 100, 400, 200, 50),
                                    text="Déja un compte ?",
                                    manager=self.manager)
Beispiel #2
0
    def __init__(self):

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

        self.title = UILabel(relative_rect=pygame.Rect(350, 50, 100, 50),
                             text='Connexion',
                             manager=self.manager)

        self.labelPseudo = UILabel(relative_rect=pygame.Rect(
            400 - 210, 142, 100, 50),
                                   text='Pseudo',
                                   manager=self.manager)

        self.pseudo = UITextEntryLine(relative_rect=pygame.Rect(
            400 - 100, 150, 200, 50),
                                      manager=self.manager)

        self.labelPassword = UILabel(relative_rect=pygame.Rect(
            400 - 210, 222, 100, 50),
                                     text='Mot de passe',
                                     manager=self.manager)

        self.password = UITextEntryLine(relative_rect=pygame.Rect(
            400 - 100, 230, 200, 50),
                                        manager=self.manager)

        self.buttonLogin = UIButton(relative_rect=pygame.Rect(
            400 - 100, 320, 200, 50),
                                    text='Se connecter',
                                    manager=self.manager)

        self.buttonSignup = UIButton(relative_rect=pygame.Rect(
            400 - 100, 400, 200, 50),
                                     text='Pas de compte ?',
                                     manager=self.manager)
Beispiel #3
0
class Speaker(pygame_gui.elements.UIWindow):
    def __init__(self, pos, manager):
        super().__init__(
            pygame.Rect(pos, (400, 128)),
            manager=manager,
            window_display_title="speaker",
            object_id="#speaker",
        )
        self.label = UILabel(
            relative_rect=pygame.Rect(-20, 10, 400, 20),
            text="",
            manager=manager,
            container=self,
        )
        self.input = UITextEntryLine(relative_rect=pygame.Rect(0, 40, 368, 30),
                                     manager=manager,
                                     container=self)
        self.engine = pyttsx3.init()
        self.engine.setProperty("rate", 150)
        self.speakthrd = None

    def process_event(self, event):
        super().process_event(event)
        if event.type == pygame.USEREVENT and event.ui_element == self.input and event.user_type == pygame_gui.UI_TEXT_ENTRY_FINISHED and (
                self.speakthrd is None or
                not self.speakthrd.is_alive()) and self.input.get_text != "":
            self.engine.say(self.input.get_text)
            self.speakthrd = threading.Thread(target=self.engine.runAndWait,
                                              args=())
            self.speakthrd.start()
            self.label.set_text(self.input.get_text)
            self.input.set_text("")
Beispiel #4
0
    def __init__(self, pos, manager):
        super().__init__(
            pygame.Rect(pos, (400,128)),
            manager=manager,
            window_display_title='speaknspell',
            object_id='#speaknspell'
        )

        self.label = UILabel(
            relative_rect=pygame.Rect(-20, 10, 400, 20),
            text='',
            manager=manager,
            container=self
        )

        self.input = UITextEntryLine(
            relative_rect=pygame.Rect(0, 40, 368, 30),
            manager=manager,
            container=self
        )

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

        self.speak('Hello, thank you for using snakeware!')
Beispiel #5
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
Beispiel #6
0
class SpeakSpell(pygame_gui.elements.UIWindow):
    speakthrd = None

    def __init__(self, pos, manager):
        super().__init__(
            pygame.Rect(pos, (400,128)),
            manager=manager,
            window_display_title='speaknspell',
            object_id='#speaknspell'
        )

        self.label = UILabel(
            relative_rect=pygame.Rect(-20, 10, 400, 20),
            text='',
            manager=manager,
            container=self
        )

        self.input = UITextEntryLine(
            relative_rect=pygame.Rect(0, 40, 368, 30),
            manager=manager,
            container=self
        )

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

        self.speak('Hello, thank you for using snakeware!')

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

        if text == '':
            return

        self.engine.say(text)
        self.speakthrd = threading.Thread(target=self.engine.runAndWait, args=())
        self.speakthrd.start()
        self.label.set_text(text)
        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())
Beispiel #7
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 = ""
Beispiel #8
0
 def __init__(self, pos, manager):
     super().__init__(
         pygame.Rect(pos, (400, 128)),
         manager=manager,
         window_display_title="speaker",
         object_id="#speaker",
     )
     self.label = UILabel(
         relative_rect=pygame.Rect(-20, 10, 400, 20),
         text="",
         manager=manager,
         container=self,
     )
     self.input = UITextEntryLine(relative_rect=pygame.Rect(0, 40, 368, 30),
                                  manager=manager,
                                  container=self)
     self.engine = pyttsx3.init()
     self.engine.setProperty("rate", 150)
     self.speakthrd = None
Beispiel #9
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")
Beispiel #10
0
    def __init__(self):

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

        self.labelParty = UILabel(relative_rect=pygame.Rect(10, 92, 150, 50),
                                  text='Nom de la partie',
                                  manager=self.manager)

        self.party = UITextEntryLine(relative_rect=pygame.Rect(
            330, 100, 150, 50),
                                     manager=self.manager)

        self.buttonCreate = UIButton(relative_rect=pygame.Rect(
            330, 200, 150, 50),
                                     text='Creer une partie',
                                     manager=self.manager)
Beispiel #11
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())
Beispiel #14
0
    def __init__(self, rect, ui_manager):
        super().__init__(rect,
                         ui_manager,
                         window_display_title='Everything Container',
                         object_id='#everything_window',
                         resizable=True)

        self.test_slider = UIHorizontalSlider(pygame.Rect(
            (int(self.rect.width / 2), int(self.rect.height * 0.70)),
            (240, 25)),
                                              50.0, (0.0, 100.0),
                                              self.ui_manager,
                                              container=self)

        self.slider_label = UILabel(
            pygame.Rect(
                (int(self.rect.width / 2) + 250, int(self.rect.height * 0.70)),
                (27, 25)),
            str(int(self.test_slider.get_current_value())),
            self.ui_manager,
            container=self)

        self.test_text_entry = UITextEntryLine(pygame.Rect(
            (int(self.rect.width / 2), int(self.rect.height * 0.50)),
            (200, -1)),
                                               self.ui_manager,
                                               container=self)
        self.test_text_entry.set_forbidden_characters('numbers')

        current_resolution_string = 'Item 1'
        self.test_drop_down_menu = UIDropDownMenu(
            [
                'Item 1', 'Item 2', 'Item 3', 'Item 4', 'Item 5', 'Item 6',
                'Item 7', 'Item 8', 'Item 9', 'Item 10', 'Item 11', 'Item 12',
                'Item 13', 'Item 14', 'Item 15', 'Item 16', 'Item 17',
                'Item 18', 'Item 19', 'Item 20', 'Item 21', 'Item 22',
                'Item 23', 'Item 24', 'Item 25', 'Item 26', 'Item 27',
                'Item 28', 'Item 29', 'Item 30'
            ],
            current_resolution_string,
            pygame.Rect(
                (int(self.rect.width / 2), int(self.rect.height * 0.3)),
                (200, 25)),
            self.ui_manager,
            container=self)

        self.health_bar = UIScreenSpaceHealthBar(pygame.Rect(
            (int(self.rect.width / 9), int(self.rect.height * 0.7)),
            (200, 20)),
                                                 self.ui_manager,
                                                 container=self)

        loaded_test_image = pygame.image.load(
            'data/images/splat.png').convert_alpha()

        self.test_image = UIImage(pygame.Rect(
            (int(self.rect.width / 9), int(self.rect.height * 0.3)),
            loaded_test_image.get_rect().size),
                                  loaded_test_image,
                                  self.ui_manager,
                                  container=self)
Beispiel #15
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)
        self.background_surface.fill(self.ui_manager.get_theme().get_colour(
            None, None, 'dark_bg'))

        self.test_button = UIButton(
            pygame.Rect((int(self.options.resolution[0] / 2),
                         int(self.options.resolution[1] * 0.90)), (100, 40)),
            '',
            self.ui_manager,
            tool_tip_text="<font face=fira_code color=normal_text size=2>"
            "<b><u>Test Tool Tip</u></b>"
            "<br><br>"
            "A little <i>test</i> of the "
            "<font color=#FFFFFF><b>tool tip</b></font>"
            " functionality."
            "<br><br>"
            "Unleash the Kraken!"
            "</font>",
            object_id='#hover_me_button')

        self.test_button_2 = UIButton(pygame.Rect(
            (int(self.options.resolution[0] / 3),
             int(self.options.resolution[1] * 0.90)), (100, 40)),
                                      'EVERYTHING',
                                      self.ui_manager,
                                      object_id='#everything_button')

        self.test_button_3 = UIButton(pygame.Rect(
            (int(self.options.resolution[0] / 6),
             int(self.options.resolution[1] * 0.90)), (100, 40)),
                                      'Scaling?',
                                      self.ui_manager,
                                      object_id='#scaling_button')

        self.test_slider = UIHorizontalSlider(pygame.Rect(
            (int(self.options.resolution[0] / 2),
             int(self.options.resolution[1] * 0.70)), (240, 25)),
                                              25.0, (0.0, 100.0),
                                              self.ui_manager,
                                              object_id='#cool_slider')

        self.test_text_entry = UITextEntryLine(pygame.Rect(
            (int(self.options.resolution[0] / 2),
             int(self.options.resolution[1] * 0.50)), (200, -1)),
                                               self.ui_manager,
                                               object_id='#main_text_entry')

        current_resolution_string = (str(self.options.resolution[0]) + 'x' +
                                     str(self.options.resolution[1]))
        self.test_drop_down = UIDropDownMenu(
            ['640x480', '800x600', '1024x768'], current_resolution_string,
            pygame.Rect((int(self.options.resolution[0] / 2),
                         int(self.options.resolution[1] * 0.3)),
                        (200, 25)), self.ui_manager)

        self.panel = UIPanel(pygame.Rect(50, 50, 200, 300),
                             starting_layer_height=4,
                             manager=self.ui_manager)

        UIButton(pygame.Rect(10, 10, 174, 30),
                 'Panel Button',
                 manager=self.ui_manager,
                 container=self.panel)

        UISelectionList(pygame.Rect(10, 50, 174, 200),
                        item_list=[
                            'Item 1', 'Item 2', 'Item 3', 'Item 4', 'Item 5',
                            'Item 6', 'Item 7', 'Item 8', 'Item 9', 'Item 10',
                            'Item 11', 'Item 12', 'Item 13', 'Item 14',
                            'Item 15', 'Item 16', 'Item 17', 'Item 18',
                            'Item 19', 'Item 20'
                        ],
                        manager=self.ui_manager,
                        container=self.panel,
                        allow_multi_select=True)
    def user_interface(self):
        WINDOW_WIDTH = 300
        WINDOW_HEIGHT = 200

        Colors = {
            'Red': (127, 0, 0),
            'Cyan': (0, 255, 255),
            'Orange': (255, 106, 0),
            'Blue': (0, 38, 255),
            'Green': (0, 153, 15),
            'Pink': (255, 0, 110),
            'Yellow': (255, 216, 0)
        }

        pygame.init()

        pygame.display.set_caption('Startup Menu')
        center = (WINDOW_WIDTH / 2, WINDOW_HEIGHT / 2)
        window = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
        manager = pygame_gui.UIManager((WINDOW_WIDTH, WINDOW_HEIGHT),
                                       './themes/button_theme.json')
        clock = pygame.time.Clock()

        background_color = (61, 120, 180)
        background = pygame.Surface((WINDOW_WIDTH, WINDOW_HEIGHT))
        background.fill(background_color)

        # color button dimensions
        button_center = [center[0], center[1] + 50]
        button_size = [30, 30]
        padding = 5
        num_buttons = 7

        colors = list(Colors.keys())

        color_buttons = []

        for index in range(-3, 4):
            position = (int(button_center[0] + index *
                            (padding + button_size[0]) - button_size[0] / 2),
                        int(button_center[1] - padding - 75 - 3))
            pygame_gui.elements.UIButton(relative_rect=pygame.Rect(
                position, button_size),
                                         text='',
                                         manager=manager,
                                         object_id='#' + colors[index + 3])

        # button dimensions
        button_width = 240
        button_height = 40
        padding = 10

        # text box dimensions
        entry_width = 240
        entry_height = 40
        padding = 10

        position = (int(center[0] - button_width / 2),
                    int(center[1] + padding / 2 + 25))
        client_button = pygame_gui.elements.UIButton(
            relative_rect=pygame.Rect(position, (button_width, button_height)),
            text='Connect',
            manager=manager,
            object_id='#standard_button')

        position = (int(center[0] - button_width / 2),
                    int(center[1] - padding / 2 - entry_height / 2 + 25))

        ip_entry = UITextEntryLine(relative_rect=pygame.Rect(
            position, (button_width - 80, button_height)),
                                   manager=manager,
                                   object_id='#text_entry')
        ip_entry.set_text('127.0.0.1')

        position = (int(center[0] - button_width / 2 + button_width - 80 +
                        padding),
                    int(center[1] - padding / 2 - entry_height / 2 + 25))

        port_entry = UITextEntryLine(relative_rect=pygame.Rect(
            position, (80 - padding, button_height)),
                                     manager=manager,
                                     object_id='#text_entry')
        port_entry.set_text('1233')

        position = (int(center[0] - button_width / 2 + 3),
                    int(center[1] - padding / 2 - entry_height / 2 + 25 - 65 +
                        3))

        name_label = pygame_gui.elements.ui_label.UILabel(
            relative_rect=pygame.Rect(position, (50, button_height - 17)),
            text='Name:',
            manager=manager,
            object_id='#text_entry')

        position = (int(center[0] - button_width / 2 + 55 + padding),
                    int(center[1] - padding / 2 - entry_height / 2 + 25 - 65))

        name_entry = UITextEntryLine(relative_rect=pygame.Rect(
            position, (button_width - 55 - padding, button_height)),
                                     manager=manager,
                                     object_id='#text_entry')

        # update screen
        pygame.display.flip()

        running = True
        client_flag = False
        server_flag = False

        while running:
            time_delta = clock.tick(60) / 1000.0
            for event in pygame.event.get():
                # close if X is clicked
                if event.type == pygame.QUIT:
                    running = False

                # close if ESC is pressed
                if event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
                    running = False

                if event.type == pygame.USEREVENT:
                    if event.user_type == pygame_gui.UI_BUTTON_PRESSED:
                        # action if client is pressed
                        if event.ui_element == client_button:
                            client_flag = True
                            # print('Client created')

                manager.process_events(event)

            manager.update(time_delta)

            window.blit(background, (0, 0))
            manager.draw_ui(window)

            pygame.display.update()

            if client_flag:
                running = False
                client_flag = False
                # self.children.append(subprocess.Popen([sys.executable, './ClientMain.py']))
                pygame.quit()
                start_instance = client(ip_entry.text, port_entry.text,
                                        name_entry.text)
Beispiel #17
0
    def __init__(self):
        pygame.init()
        self.size = [INTRO_SCREEN_WIDTH, INTRO_SCREEN_HEIGHT]
        self.screen = pygame.display.set_mode(self.size)
        self.con_win = None
        self.game_level = 4
        self.game = None
        self.start_game = False
        self.game_nb_players = 4  # TODO The max number of players should be in function of the size of the desk
        self.game_nb_online_players = 1
        self.nb_p_c = 1
        # self.block_list
        self.player_name = "John"
        # self.player_name = "IA Show"
        self.player_type = "offline"
        self.host_address = "localhost"
        self.survival_mode = True
        self.all_sprites_list = pygame.sprite.Group()
        self.block_list = pygame.sprite.Group()
        self.clicked = False
        self.ui_manager = pygame_gui.UIManager(
            (INTRO_SCREEN_WIDTH, INTRO_SCREEN_HEIGHT))
        self.ui_manager.preload_fonts([{
            'name': 'fira_code',
            'point_size': 10,
            'style': 'bold'
        }, {
            'name': 'fira_code',
            'point_size': 10,
            'style': 'regular'
        }, {
            'name': 'fira_code',
            'point_size': 10,
            'style': 'italic'
        }, {
            'name': 'fira_code',
            'point_size': 14,
            'style': 'italic'
        }, {
            'name': 'fira_code',
            'point_size': 14,
            'style': 'bold'
        }, {
            'name': 'fira_code',
            'point_size': 14,
            'style': 'bold_italic'
        }])
        step = 40
        s = [150, 35]
        self.name_label = UILabel(pygame.rect.Rect((0, step), s),
                                  "Name",
                                  manager=self.ui_manager)
        self.name_value = UITextEntryLine(
            pygame.Rect((self.name_label.relative_rect.width,
                         self.name_label.relative_rect.y), (200, -1)),
            self.ui_manager)
        self.name_value.set_text(self.player_name)
        # The level
        self.game_level_label = UILabel(pygame.rect.Rect((0, step * 2), s),
                                        "Level",
                                        manager=self.ui_manager)
        self.game_level_drop = UIDropDownMenu(
            [str(i) for i in range(1, 5, 1)], f"{self.game_level}",
            pygame.rect.Rect(((s[0] - step) // 2, step * 3),
                             (50, 35)), self.ui_manager)
        self.nb_players_label = UILabel(pygame.rect.Rect(
            (s[0], self.game_level_label.relative_rect.y), s),
                                        "NB players",
                                        manager=self.ui_manager)
        self.nb_players_drop = UIDropDownMenu([str(i) for i in range(2, 7, 1)],
                                              f"{self.game_nb_players}",
                                              pygame.Rect(
                                                  (int(1.3 * s[0]), step * 3),
                                                  (50, 35)), self.ui_manager)

        self.nb_p_c_label = UILabel(pygame.rect.Rect(
            (2 * s[0], self.game_level_label.relative_rect.y), s),
                                    "NB playing cards",
                                    manager=self.ui_manager)

        self.nb_p_c_players_drop = UIDropDownMenu(
            [str(i) for i in range(1, 5, 1)], f"{self.nb_p_c}",
            pygame.Rect((int(2.3 * s[0]), step * 3),
                        (50, 35)), self.ui_manager)
        self.survival_label = UILabel(pygame.rect.Rect(
            (3 * s[0], self.game_level_label.relative_rect.y), s),
                                      "Survival mode",
                                      manager=self.ui_manager)

        self.survival_drop = UIDropDownMenu(
            ["yes", "no"], f"{'yes' if self.survival_mode else 'no'}",
            pygame.Rect((int(3.3 * s[0]), step * 3),
                        (60, 35)), self.ui_manager)

        self.start_game_btn = UIButton(
            pygame.Rect((INTRO_SCREEN_WIDTH - 200, INTRO_SCREEN_HEIGHT - 50),
                        (100, 40)), 'START', self.ui_manager)
        self.resume_game_btn = UIButton(
            pygame.Rect(
                (INTRO_SCREEN_WIDTH // 2 - 50, INTRO_SCREEN_HEIGHT - 50),
                (100, 40)), 'RESUME', self.ui_manager)
        self.quit_game_btn = UIButton(
            pygame.Rect((100, INTRO_SCREEN_HEIGHT - 50), (100, 40)), 'QUIT',
            self.ui_manager)
        UILabel(pygame.rect.Rect((10, int(step * 6.5 - s[1])), s),
                "On-line Settings",
                manager=self.ui_manager)
        self.online_panel = UIPanel(pygame.rect.Rect(
            (10, int(step * 6.5)), (INTRO_SCREEN_WIDTH - 20, step * 5)),
                                    starting_layer_height=4,
                                    manager=self.ui_manager)

        self.nb_online_players_label = UILabel(pygame.rect.Rect((s[0], 0), s),
                                               "Online players",
                                               manager=self.ui_manager,
                                               container=self.online_panel)

        self.nb_online_players_drop = UIDropDownMenu(
            [str(i) for i in range(1, 6, 1)],
            f"{self.game_nb_online_players}",
            pygame.Rect((int(1.3 * (s[0])), step), (55, 35)),
            self.ui_manager,
            container=self.online_panel)
        self.player_type_label = UILabel(pygame.rect.Rect((0, 0), s),
                                         "Player type",
                                         manager=self.ui_manager,
                                         container=self.online_panel)
        self.player_type_drop = UIDropDownMenu(["server", "client", "offline"],
                                               f"{self.player_type}",
                                               pygame.Rect(
                                                   (int(0.17 * s[0]), step),
                                                   (100, 35)),
                                               self.ui_manager,
                                               container=self.online_panel)
        self.host_address_label = UILabel(pygame.rect.Rect((s[0], 0), s),
                                          "Host address",
                                          manager=self.ui_manager,
                                          container=self.online_panel)
        self.host_address_entry = UITextEntryLine(pygame.Rect((s[0], step),
                                                              (150, 35)),
                                                  self.ui_manager,
                                                  container=self.online_panel)
        self.host_address_entry.set_text(self.host_address)
        if self.player_type != "client":
            # self.host_address_label.is_enabled = False
            # self.host_address_entry.is_enabled = False

            self.game_level_drop.show()
            self.game_level_label.show()
            self.nb_players_drop.show()
            self.nb_players_label.show()
            self.nb_p_c_players_drop.show()
            self.nb_p_c_label.show()
            self.survival_drop.show()
            self.survival_label.show()

            self.host_address_entry.hide()
            self.host_address_label.hide()
        else:
            # self.host_address_label.is_enabled = True
            # self.host_address_entry.is_enabled = True

            self.game_level_drop.hide()
            self.game_level_label.hide()
            self.nb_players_drop.hide()
            self.nb_players_label.hide()
            self.nb_p_c_players_drop.hide()
            self.nb_p_c_label.hide()
            self.survival_drop.hide()
            self.survival_label.hide()

            self.host_address_label.show()
            self.host_address_entry.show()

        if self.player_type != "server":
            # self.nb_online_players_drop.is_enabled = False
            self.nb_online_players_drop.hide()
            self.nb_online_players_label.hide()
        else:
            # self.nb_online_players_drop.is_enabled = True
            self.nb_online_players_drop.show()
            self.nb_online_players_label.show()
Beispiel #18
0
class UIFileDialog(UIWindow):
    """
    A dialog window for handling file selection operations. The dialog will let you pick a file
    from a file system but won't do anything with it once you have, the path will just be returned
    leaving it up to the rest of the application to decide what to do with it.

    :param rect: The size and position of the file dialog window. Includes the size of shadow,
                 border and title bar.
    :param manager: The manager for the whole of the UI.
    :param window_title: The title for the window, defaults to 'File Dialog'
    :param initial_file_path: The initial path to open the file dialog at.
    :param object_id: The object ID for the window, used for theming - defaults to '#file_dialog'
    :param visible: Whether the element is visible by default.
    """
    def __init__(self,
                 rect: pygame.Rect,
                 manager: IUIManagerInterface,
                 window_title: str = 'File Dialog',
                 initial_file_path: Union[str, None] = None,
                 object_id: Union[ObjectID,
                                  str] = ObjectID('#file_dialog', None),
                 allow_existing_files_only: bool = False,
                 allow_picking_directories: bool = False,
                 visible: int = 1):

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

        minimum_dimensions = (260, 300)
        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.allow_existing_files_only = allow_existing_files_only
        self.allow_picking_directories = allow_picking_directories

        self.delete_confirmation_dialog = None  # type: Union[UIConfirmationDialog, None]
        self.current_file_path = None  # type: Union[Path, None]

        if initial_file_path is not None:
            pathed_initial_file_path = Path(initial_file_path)
            if pathed_initial_file_path.exists(
            ) and not pathed_initial_file_path.is_file():
                self.current_directory_path = str(
                    pathed_initial_file_path.resolve())
                if self.allow_picking_directories:
                    self.current_file_path = self.current_directory_path
            elif pathed_initial_file_path.exists(
            ) and pathed_initial_file_path.is_file():
                self.current_file_path = pathed_initial_file_path.resolve()
                self.current_directory_path = str(
                    pathed_initial_file_path.parent.resolve())
            elif pathed_initial_file_path.parent.exists():
                self.current_directory_path = str(
                    pathed_initial_file_path.parent.resolve())
                self.current_file_path = (
                    Path(initial_file_path).parent.resolve() /
                    Path(initial_file_path).name)
        else:
            self.current_directory_path = str(Path('.').resolve())

        self.last_valid_directory_path = self.current_directory_path

        self.current_file_list = None  # type: Union[List[str], None]
        self.update_current_file_list()

        self.ok_button = UIButton(relative_rect=pygame.Rect(
            -220, -40, 100, 30),
                                  text='OK',
                                  manager=self.ui_manager,
                                  container=self,
                                  object_id='#ok_button',
                                  anchors={
                                      'left': 'right',
                                      'right': 'right',
                                      'top': 'bottom',
                                      'bottom': 'bottom'
                                  })
        if not self._validate_file_path(self.current_file_path):
            self.ok_button.disable()

        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'
                                      })

        self.home_button = UIButton(relative_rect=pygame.Rect(10, 10, 20, 20),
                                    text='⌂',
                                    tool_tip_text='Home Directory',
                                    manager=self.ui_manager,
                                    container=self,
                                    object_id='#home_icon_button',
                                    anchors={
                                        'left': 'left',
                                        'right': 'left',
                                        'top': 'top',
                                        'bottom': 'top'
                                    })

        self.delete_button = UIButton(relative_rect=pygame.Rect(
            32, 10, 20, 20),
                                      text='⌧',
                                      tool_tip_text='Delete',
                                      manager=self.ui_manager,
                                      container=self,
                                      object_id='#delete_icon_button',
                                      anchors={
                                          'left': 'left',
                                          'right': 'left',
                                          'top': 'top',
                                          'bottom': 'top'
                                      })
        if not self._validate_path_exists_and_of_allowed_type(
                self.current_file_path, allow_directories=False):
            self.delete_button.disable()

        self.parent_directory_button = UIButton(
            relative_rect=pygame.Rect(54, 10, 20, 20),
            text='↑',
            tool_tip_text='Parent Directory',
            manager=self.ui_manager,
            container=self,
            object_id='#parent_icon_button',
            anchors={
                'left': 'left',
                'right': 'left',
                'top': 'top',
                'bottom': 'top'
            })

        self.refresh_button = UIButton(relative_rect=pygame.Rect(
            76, 10, 20, 20),
                                       text='⇪',
                                       tool_tip_text='Refresh Directory',
                                       manager=self.ui_manager,
                                       container=self,
                                       object_id='#refresh_icon_button',
                                       anchors={
                                           'left': 'left',
                                           'right': 'left',
                                           'top': 'top',
                                           'bottom': 'top'
                                       })

        text_line_rect = pygame.Rect(10, 40,
                                     self.get_container().get_size()[0] - 20,
                                     25)
        self.file_path_text_line = UITextEntryLine(
            relative_rect=text_line_rect,
            manager=self.ui_manager,
            container=self,
            object_id='#file_path_text_line',
            anchors={
                'left': 'left',
                'right': 'right',
                'top': 'top',
                'bottom': 'top'
            })
        if self.current_file_path is not None:
            self.file_path_text_line.set_text(str(self.current_file_path))
            self._highlight_file_name_for_editing()
        else:
            self.file_path_text_line.set_text(str(self.current_directory_path))

        file_selection_rect = pygame.Rect(
            10, 80,
            self.get_container().get_size()[0] - 20,
            self.get_container().get_size()[1] - 130)
        self.file_selection_list = UISelectionList(
            relative_rect=file_selection_rect,
            item_list=self.current_file_list,
            manager=self.ui_manager,
            container=self,
            object_id='#file_display_list',
            anchors={
                'left': 'left',
                'right': 'right',
                'top': 'top',
                'bottom': 'bottom'
            })

    def _highlight_file_name_for_editing(self):
        # try highlighting the file name
        if self.current_file_path is None or self.allow_existing_files_only:
            return
        highlight_start = self.file_path_text_line.get_text().find(
            self.current_file_path.stem)
        highlight_end = highlight_start + len(self.current_file_path.stem)
        self.file_path_text_line.select_range[0] = highlight_start
        self.file_path_text_line.select_range[1] = highlight_end
        self.file_path_text_line.cursor_has_moved_recently = True
        self.file_path_text_line.edit_position = highlight_end

        text_clip_width = (self.file_path_text_line.rect.width -
                           (self.file_path_text_line.padding[0] * 2) -
                           (self.file_path_text_line.shape_corner_radius * 2) -
                           (self.file_path_text_line.border_width * 2) -
                           (self.file_path_text_line.shadow_width * 2))

        text_width = self.file_path_text_line.font.size(
            self.file_path_text_line.get_text())[0]
        self.file_path_text_line.start_text_offset = max(
            0, text_width - text_clip_width)
        if not self.file_path_text_line.is_focused:
            self.file_path_text_line.focus()

    def update_current_file_list(self):
        """
        Updates the currently displayed list of files and directories. Usually called when the
        directory path has changed.
        """
        try:
            directories_on_path = [
                f.name for f in Path(self.current_directory_path).iterdir()
                if not f.is_file()
            ]
            directories_on_path = sorted(directories_on_path, key=str.casefold)
            directories_on_path_tuples = [(f, '#directory_list_item')
                                          for f in directories_on_path]

            files_on_path = [
                f.name for f in Path(self.current_directory_path).iterdir()
                if f.is_file()
            ]
            files_on_path = sorted(files_on_path, key=str.casefold)
            files_on_path_tuples = [(f, '#file_list_item')
                                    for f in files_on_path]

            self.current_file_list = directories_on_path_tuples + files_on_path_tuples
        except (PermissionError, FileNotFoundError):
            self.current_directory_path = self.last_valid_directory_path
            self.update_current_file_list()
        else:
            self.last_valid_directory_path = self.current_directory_path

    def _validate_file_path(self, path_to_validate: Path) -> bool:
        if self.allow_existing_files_only:
            return self._validate_path_exists_and_of_allowed_type(
                path_to_validate, self.allow_picking_directories)
        else:
            return self._validate_path_in_existing_directory(path_to_validate)

    @staticmethod
    def _validate_path_in_existing_directory(path_to_validate: Path) -> bool:
        """
        Checks the selected path is valid.

        :return: True if valid.

        """
        if path_to_validate is None:
            return False
        return len(
            path_to_validate.name) > 0 and path_to_validate.parent.exists()

    @staticmethod
    def _validate_path_exists_and_of_allowed_type(
            path_to_validate: Path, allow_directories: bool) -> bool:
        """
        Checks the selected path is valid.

        :return: True if valid.

        """
        if path_to_validate is None:
            return False
        if allow_directories:
            valid_type = (path_to_validate.is_file()
                          or path_to_validate.is_dir())
        else:
            valid_type = path_to_validate.is_file()
        return path_to_validate.exists() and valid_type

    def process_event(self, event: pygame.event.Event) -> bool:
        """
        Handles events that this UI element is interested in. There are a lot of buttons in the
        file dialog.

        :param event: The pygame Event to process.

        :return: True if event is consumed by this element and should not be passed on to other
                 elements.

        """
        handled = super().process_event(event)

        self._process_ok_cancel_events(event)
        self._process_confirmation_dialog_events(event)
        self._process_mini_file_operation_button_events(event)
        self._process_file_path_entry_events(event)
        self._process_file_list_events(event)

        return handled

    def _process_file_path_entry_events(self, event):
        """
        Handle events coming from text entry element which displays the current file path.

        :param event: event to check.

        """
        if (event.type != pygame.USEREVENT or event.user_type
                not in [UI_TEXT_ENTRY_FINISHED, UI_TEXT_ENTRY_CHANGED]
                or event.ui_element != self.file_path_text_line):
            return
        entered_file_path = Path(
            self.file_path_text_line.get_text()).absolute()
        if self._validate_file_path(entered_file_path):
            if len(entered_file_path.name) > 0 and (
                    entered_file_path.is_file()
                    or not entered_file_path.exists()):
                self.current_file_path = entered_file_path

                if self._validate_path_exists_and_of_allowed_type(
                        self.current_file_path, allow_directories=False):
                    self.delete_button.enable()
                else:
                    self.delete_button.disable()
                self.ok_button.enable()
            else:
                self.current_directory_path = str(entered_file_path)
                self.current_file_path = None
                self.delete_button.disable()
                self.ok_button.disable()

            if event.user_type == UI_TEXT_ENTRY_FINISHED:
                if len(entered_file_path.name
                       ) > 0 and entered_file_path.is_dir():
                    self.current_directory_path = str(entered_file_path)
                elif len(entered_file_path.name) > 0 and (
                        entered_file_path.is_file()
                        or not entered_file_path.exists()):
                    self.current_directory_path = str(
                        entered_file_path.parent.absolute())
                else:
                    self.current_directory_path = str(entered_file_path)

                self.update_current_file_list()
                self.file_selection_list.set_item_list(self.current_file_list)

                if self.current_file_path is not None:
                    self.file_path_text_line.set_text(
                        str(self.current_file_path))
                else:
                    self.file_path_text_line.set_text(
                        self.current_directory_path)
        else:
            self.current_directory_path = self.last_valid_directory_path
            self.current_file_path = None
            self.delete_button.disable()
            self.ok_button.disable()

    def _process_file_list_events(self, event):
        """
        Handle events coming from the file/folder list.

        :param event: event to check.

        """
        if (event.type == pygame.USEREVENT
                and event.user_type == UI_SELECTION_LIST_NEW_SELECTION
                and event.ui_element == self.file_selection_list):
            new_selection_file_path = Path(
                self.current_directory_path) / event.text
            if self._validate_path_exists_and_of_allowed_type(
                    new_selection_file_path, self.allow_picking_directories):
                self.current_file_path = new_selection_file_path
                self.file_path_text_line.set_text(str(self.current_file_path))
                self._highlight_file_name_for_editing()
                self.ok_button.enable()
                if self._validate_path_exists_and_of_allowed_type(
                        self.current_file_path, allow_directories=False):
                    self.delete_button.enable()
                else:
                    self.delete_button.disable()
            else:
                self.ok_button.disable()
                self.delete_button.disable()
        if (event.type == pygame.USEREVENT and event.user_type
                == UI_SELECTION_LIST_DOUBLE_CLICKED_SELECTION
                and event.ui_element == self.file_selection_list):
            new_directory_file_path = Path(
                self.current_directory_path) / event.text
            self._change_directory_path(new_directory_file_path)

    def _change_directory_path(self, new_directory_path: Path):
        """
        Change the current directory path and update everything that needs to update when that
        happens.

        :param new_directory_path: The new path to change to.
        """
        if not new_directory_path.exists() or new_directory_path.is_file():
            return
        self.current_directory_path = str(new_directory_path.resolve())
        self.update_current_file_list()
        self.file_selection_list.set_item_list(self.current_file_list)

        if self.current_file_path is not None and not self.allow_existing_files_only:
            self.current_file_path = (new_directory_path /
                                      self.current_file_path.name).resolve()
            self.file_path_text_line.set_text(str(self.current_file_path))
            self._highlight_file_name_for_editing()
            self.ok_button.enable()
            if self._validate_path_exists_and_of_allowed_type(
                    self.current_file_path, allow_directories=False):
                self.delete_button.enable()
            else:
                self.delete_button.disable()
        else:
            self.current_file_path = None
            self.file_path_text_line.set_text(self.current_directory_path)
            self.delete_button.disable()
            self.ok_button.disable()

    def _process_confirmation_dialog_events(self, event):
        """
        Handle any events coming from the confirmation dialog if that's up.

        :param event: event to check.

        """
        if (event.type != pygame.USEREVENT
                or event.user_type != UI_CONFIRMATION_DIALOG_CONFIRMED
                or event.ui_element != self.delete_confirmation_dialog):
            return
        try:
            self.current_file_path.unlink()
        except (PermissionError, FileNotFoundError):
            pass
        else:
            self.current_file_path = None
            self.delete_button.disable()
            self.ok_button.disable()

            self.update_current_file_list()
            self.file_path_text_line.set_text(self.current_directory_path)
            self.file_selection_list.set_item_list(self.current_file_list)

    def _process_mini_file_operation_button_events(self, event):
        """
        Handle what happens when you press one of the tiny file/folder operation buttons.

        :param event: event to check.

        """
        if (event.type == pygame.USEREVENT
                and event.user_type == UI_BUTTON_PRESSED
                and event.ui_element == self.delete_button):
            confirmation_rect = pygame.Rect(0, 0, 300, 200)
            confirmation_rect.center = self.rect.center

            selected_file_name = self.current_file_path.name
            long_desc = "Delete " + str(selected_file_name) + "?"
            self.delete_confirmation_dialog = UIConfirmationDialog(
                rect=confirmation_rect,
                manager=self.ui_manager,
                action_long_desc=long_desc,
                action_short_name='Delete',
                window_title='Delete')
        if (event.type == pygame.USEREVENT
                and event.user_type == UI_BUTTON_PRESSED
                and event.ui_element == self.parent_directory_button):
            self._change_directory_path(
                Path(self.current_directory_path).parent)
        if (event.type == pygame.USEREVENT
                and event.user_type == UI_BUTTON_PRESSED
                and event.ui_element == self.refresh_button):
            self._change_directory_path(Path(self.current_directory_path))
        if (event.type == pygame.USEREVENT
                and event.user_type == UI_BUTTON_PRESSED
                and event.ui_element == self.home_button):
            self._change_directory_path(Path.home())

    def _process_ok_cancel_events(self, event):
        """
        Handle what happens when you press OK and Cancel.

        :param event: event to check.

        """
        if (event.type == pygame.USEREVENT
                and event.user_type == UI_BUTTON_PRESSED
                and event.ui_element == self.cancel_button):
            self.kill()
        if (event.type == pygame.USEREVENT
                and event.user_type == UI_BUTTON_PRESSED
                and event.ui_element == self.ok_button
                and self._validate_file_path(self.current_file_path)):
            event_data = {
                'user_type': UI_FILE_DIALOG_PATH_PICKED,
                'text': str(self.current_file_path),
                'ui_element': self,
                'ui_object_id': self.most_specific_combined_id
            }
            new_file_chosen_event = pygame.event.Event(pygame.USEREVENT,
                                                       event_data)
            pygame.event.post(new_file_chosen_event)
            self.kill()
Beispiel #19
0
class UIFileDialog(UIWindow):
    """
    A dialog window for handling file selection operations. The dialog will let you pick a file
    from a file system but won't do anything with it once you have, the path will just be returned
    leaving it up to the rest of the application to decide what to do with it.

    TODO: This works fine for loading files, but can it be adjusted to allow for saving files?

    :param rect: The size and position of the file dialog window. Includes the size of shadow,
                 border and title bar.
    :param manager: The manager for the whole of the UI.
    :param window_title: The title for the window, defaults to 'File Dialog'
    :param initial_file_path: The initial path to open the file dialog at.
    :param object_id: The object ID for the window, used for theming - defaults to '#file_dialog'

    """
    def __init__(self,
                 rect: pygame.Rect,
                 manager: IUIManagerInterface,
                 window_title: str = 'File Dialog',
                 initial_file_path: Union[str, None] = None,
                 object_id: str = '#file_dialog'):

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

        minimum_dimensions = (260, 300)
        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.delete_confirmation_dialog = None  # type: Union[None, UIConfirmationDialog]

        if initial_file_path is not None:
            if exists(initial_file_path):
                self.current_directory_path = abspath(initial_file_path)
        else:
            self.current_directory_path = abspath('.')

        self.last_valid_path = None

        self.selected_file_path = None

        self.current_file_list = None  # type: Union[None, List[str]]
        self.update_current_file_list()

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

        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'
                                      })

        self.home_button = UIButton(relative_rect=pygame.Rect(10, 10, 20, 20),
                                    text='⌂',
                                    tool_tip_text='Home Directory',
                                    manager=self.ui_manager,
                                    container=self,
                                    object_id='#home_icon_button',
                                    anchors={
                                        'left': 'left',
                                        'right': 'left',
                                        'top': 'top',
                                        'bottom': 'top'
                                    })

        self.delete_button = UIButton(relative_rect=pygame.Rect(
            32, 10, 20, 20),
                                      text='⌧',
                                      tool_tip_text='Delete',
                                      manager=self.ui_manager,
                                      container=self,
                                      object_id='#delete_icon_button',
                                      anchors={
                                          'left': 'left',
                                          'right': 'left',
                                          'top': 'top',
                                          'bottom': 'top'
                                      })
        self.delete_button.disable()

        self.parent_directory_button = UIButton(
            relative_rect=pygame.Rect(54, 10, 20, 20),
            text='↑',
            tool_tip_text='Parent Directory',
            manager=self.ui_manager,
            container=self,
            object_id='#parent_icon_button',
            anchors={
                'left': 'left',
                'right': 'left',
                'top': 'top',
                'bottom': 'top'
            })

        self.refresh_button = UIButton(relative_rect=pygame.Rect(
            76, 10, 20, 20),
                                       text='⇪',
                                       tool_tip_text='Refresh Directory',
                                       manager=self.ui_manager,
                                       container=self,
                                       object_id='#refresh_icon_button',
                                       anchors={
                                           'left': 'left',
                                           'right': 'left',
                                           'top': 'top',
                                           'bottom': 'top'
                                       })

        text_line_rect = pygame.Rect(
            10, 40,
            self.get_container().relative_rect.width - 20, 25)
        self.file_path_text_line = UITextEntryLine(
            relative_rect=text_line_rect,
            manager=self.ui_manager,
            container=self,
            object_id='#file_path_text_line',
            anchors={
                'left': 'left',
                'right': 'right',
                'top': 'top',
                'bottom': 'top'
            })
        self.file_path_text_line.set_text(self.current_directory_path)

        file_selection_rect = pygame.Rect(
            10, 80,
            self.get_container().relative_rect.width - 20,
            self.get_container().relative_rect.height - 130)
        self.file_selection_list = UISelectionList(
            relative_rect=file_selection_rect,
            item_list=self.current_file_list,
            manager=self.ui_manager,
            container=self,
            object_id='#file_display_list',
            anchors={
                'left': 'left',
                'right': 'right',
                'top': 'top',
                'bottom': 'bottom'
            })

    def update_current_file_list(self):
        """
        Updates the currently displayed list of files and directories. Usually called when the
        directory path has changed.
        """
        try:
            directories_on_path = [
                f for f in listdir(self.current_directory_path)
                if not isfile(join(self.current_directory_path, f))
            ]
            directories_on_path = sorted(directories_on_path, key=str.casefold)
            directories_on_path_tuples = [(f, '#directory_list_item')
                                          for f in directories_on_path]

            files_on_path = [
                f for f in listdir(self.current_directory_path)
                if isfile(join(self.current_directory_path, f))
            ]
            files_on_path = sorted(files_on_path, key=str.casefold)
            files_on_path_tuples = [(f, '#file_list_item')
                                    for f in files_on_path]

            self.current_file_list = directories_on_path_tuples + files_on_path_tuples
        except (PermissionError, FileNotFoundError):
            self.current_directory_path = self.last_valid_path
            self.update_current_file_list()
        else:
            self.last_valid_path = self.current_directory_path

    def _validate_selected_path(self) -> bool:
        """
        Checks the selected path is valid.

        :return: True if valid.

        """
        if self.selected_file_path is None:
            return False
        return exists(self.selected_file_path) and isfile(
            self.selected_file_path)

    def process_event(self, event: pygame.event.Event) -> bool:
        """
        Handles events that this UI element is interested in. There are a lot of buttons in the
        file dialog.

        :param event: The pygame Event to process.

        :return: True if event is consumed by this element and should not be passed on to other
                 elements.

        """
        handled = super().process_event(event)

        self._process_ok_cancel_events(event)
        self._process_confirmation_dialog_events(event)
        self._process_mini_file_operation_button_events(event)
        self._process_file_path_entry_events(event)
        self._process_file_list_events(event)

        return handled

    def _process_file_path_entry_events(self, event):
        """
        Handle events coming from text entry element which displays the current file path.

        :param event: event to check.

        """
        if (event.type == pygame.USEREVENT
                and event.user_type == UI_TEXT_ENTRY_FINISHED
                and event.ui_element == self.file_path_text_line):
            entered_file_path = self.file_path_text_line.get_text()
            if exists(entered_file_path):
                self.current_directory_path = abspath(entered_file_path)

                self.update_current_file_list()
                self.file_path_text_line.set_text(self.current_directory_path)
                self.file_selection_list.set_item_list(self.current_file_list)

                self.delete_button.disable()
                self.ok_button.disable()

    def _process_file_list_events(self, event):
        """
        Handle events coming from the file/folder list.

        :param event: event to check.

        """
        if (event.type == pygame.USEREVENT
                and event.user_type == UI_SELECTION_LIST_NEW_SELECTION
                and event.ui_element == self.file_selection_list):
            new_selection_file_path = join(self.current_directory_path,
                                           event.text)
            if exists(new_selection_file_path) and isfile(
                    new_selection_file_path):
                self.selected_file_path = new_selection_file_path
                self.ok_button.enable()
                self.delete_button.enable()
            else:
                self.ok_button.disable()
                self.delete_button.disable()
        if (event.type == pygame.USEREVENT and event.user_type
                == UI_SELECTION_LIST_DOUBLE_CLICKED_SELECTION
                and event.ui_element == self.file_selection_list):
            new_directory_file_path = join(self.current_directory_path,
                                           event.text)
            if exists(new_directory_file_path
                      ) and not isfile(new_directory_file_path):
                self.current_directory_path = abspath(new_directory_file_path)

                self.update_current_file_list()
                self.file_path_text_line.set_text(self.current_directory_path)
                self.file_selection_list.set_item_list(self.current_file_list)

                self.delete_button.disable()
                self.ok_button.disable()

    def _process_confirmation_dialog_events(self, event):
        """
        Handle any events coming from the confirmation dialog if that's up.

        :param event: event to check.

        """
        if (event.type == pygame.USEREVENT
                and event.user_type == UI_CONFIRMATION_DIALOG_CONFIRMED
                and event.ui_element == self.delete_confirmation_dialog):
            try:
                Path(self.selected_file_path).unlink()
                self.delete_button.disable()

                self.update_current_file_list()
                self.file_path_text_line.set_text(self.current_directory_path)
                self.file_selection_list.set_item_list(self.current_file_list)
            except (PermissionError, FileNotFoundError):
                pass

    def _process_mini_file_operation_button_events(self, event):
        """
        Handle what happens when you press one of the tiny file/folder operation buttons.

        :param event: event to check.

        """
        if (event.type == pygame.USEREVENT
                and event.user_type == UI_BUTTON_PRESSED
                and event.ui_element == self.delete_button):
            confirmation_rect = pygame.Rect(0, 0, 300, 200)
            confirmation_rect.center = self.rect.center

            selected_file_name = Path(self.selected_file_path).name
            long_desc = "Delete " + str(selected_file_name) + "?"
            self.delete_confirmation_dialog = UIConfirmationDialog(
                rect=confirmation_rect,
                manager=self.ui_manager,
                action_long_desc=long_desc,
                action_short_name='Delete',
                window_title='Delete')
        if (event.type == pygame.USEREVENT
                and event.user_type == UI_BUTTON_PRESSED
                and event.ui_element == self.parent_directory_button):
            self.current_directory_path = str(
                Path(self.current_directory_path).parent)

            self.update_current_file_list()
            self.file_path_text_line.set_text(self.current_directory_path)
            self.file_selection_list.set_item_list(self.current_file_list)

            self.delete_button.disable()
            self.ok_button.disable()
        if (event.type == pygame.USEREVENT
                and event.user_type == UI_BUTTON_PRESSED
                and event.ui_element == self.refresh_button):
            self.update_current_file_list()
            self.file_path_text_line.set_text(self.current_directory_path)
            self.file_selection_list.set_item_list(self.current_file_list)

            self.delete_button.disable()
            self.ok_button.disable()
        if (event.type == pygame.USEREVENT
                and event.user_type == UI_BUTTON_PRESSED
                and event.ui_element == self.home_button):
            self.current_directory_path = str(Path.home())

            self.update_current_file_list()
            self.file_path_text_line.set_text(self.current_directory_path)
            self.file_selection_list.set_item_list(self.current_file_list)

            self.delete_button.disable()
            self.ok_button.disable()

    def _process_ok_cancel_events(self, event):
        """
        Handle what happens when you press OK and Cancel.

        :param event: event to check.

        """
        if (event.type == pygame.USEREVENT
                and event.user_type == UI_BUTTON_PRESSED
                and event.ui_element == self.cancel_button):
            self.kill()
        if (event.type == pygame.USEREVENT
                and event.user_type == UI_BUTTON_PRESSED
                and event.ui_element == self.ok_button
                and self._validate_selected_path()):
            event_data = {
                'user_type': UI_FILE_DIALOG_PATH_PICKED,
                'text': self.selected_file_path,
                'ui_element': self,
                'ui_object_id': self.most_specific_combined_id
            }
            new_file_chosen_event = pygame.event.Event(pygame.USEREVENT,
                                                       event_data)
            pygame.event.post(new_file_chosen_event)
            self.kill()
Beispiel #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()

        # 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()
Beispiel #21
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 build_gui(self):
        super().build_gui()
        panel_rect = Rect(
            0, 0, 500,
            self.display.get_rect().height - (get_param('panel_padding') * 2))
        panel_rect.centerx = self.display.get_rect().centerx
        panel_rect.y = get_param('panel_padding')
        self.ui_elements['panel'] = UIPanel(panel_rect, 1, self.gui)
        # all other elements are relative
        scene_label_rect = Rect(0, 0, 400, get_param('element_height'))
        scene_label_rect.y = get_param('element_padding')
        scene_label_rect.centerx = panel_rect.w // 2  # midpoint of the panel
        self.ui_elements['scene_label'] = UILabel(scene_label_rect,
                                                  "Generate Random Map",
                                                  self.gui,
                                                  self.ui_elements['panel'])
        # map size
        label_rect = Rect(0, 0, 150, get_param('element_height'))
        label_rect.y += scene_label_rect.bottom + get_param('element_padding')
        dd_rect = Rect(0, 0, 250, get_param('element_height'))
        dd_rect.y = label_rect.y
        label_rect.centerx = 125
        dd_rect.centerx = 325
        self.ui_elements['d_size_label'] = UILabel(label_rect, "Map Size",
                                                   self.gui,
                                                   self.ui_elements['panel'])
        self.ui_elements['dd_map_size'] = UIDropDownMenu(
            ['64', '128', '256'], '64', dd_rect, self.gui,
            self.ui_elements['panel'])
        # Seed
        label_rect.y += get_param('element_height') + get_param(
            'element_padding')
        ip_rect = Rect(0, 0, 180, get_param('element_height'))
        ip_rect.centerx = (panel_rect.w // 2) + 30
        ip_rect.y = label_rect.y
        s_btn_rect = Rect(0, 0, 60, get_param('element_height'))
        s_btn_rect.x = ip_rect.right + get_param('element_padding')
        s_btn_rect.y = ip_rect.y
        self.ui_elements['seed_label'] = UILabel(label_rect, 'Map Seed',
                                                 self.gui,
                                                 self.ui_elements['panel'])
        self.ui_elements['input_seed'] = UITextEntryLine(
            ip_rect, self.gui, self.ui_elements['panel'])
        self.ui_elements['btn_rnd_seed'] = UIButton(s_btn_rect, 'Random',
                                                    self.gui,
                                                    self.ui_elements['panel'])
        # I want to add two sliders, 1 for mountains and 1 for water, these would be used to control the upper
        # and lower limits of the height mapping.
        h_sl_ops = (0, 100)
        h_sl_sel = 50
        label_rect.y += get_param('element_height') + get_param(
            'element_padding')
        h_sl_rect = Rect(0, 0, 200, get_param('element_height'))
        h_sl_rect.centerx = (panel_rect.w //
                             2) + get_param('element_padding') + 30
        h_sl_rect.y = label_rect.y
        self.ui_elements['hsl_grass'] = UILabel(label_rect, 'Grass', self.gui,
                                                self.ui_elements['panel'])
        self.ui_elements['hs_grass'] = UIHorizontalSlider(
            h_sl_rect, h_sl_sel, h_sl_ops, self.gui, self.ui_elements['panel'])

        label_rect.y += get_param('element_height') + get_param(
            'element_padding')
        h_sl_rect.y = label_rect.y
        self.ui_elements['hsl_water'] = UILabel(label_rect, 'Water', self.gui,
                                                self.ui_elements['panel'])
        self.ui_elements['hs_water'] = UIHorizontalSlider(
            h_sl_rect, h_sl_sel, h_sl_ops, self.gui, self.ui_elements['panel'])

        label_rect.y += get_param('element_height') + get_param(
            'element_padding')
        h_sl_rect.y = label_rect.y
        self.ui_elements['hsl_mountain'] = UILabel(label_rect, 'Mountain',
                                                   self.gui,
                                                   self.ui_elements['panel'])
        self.ui_elements['hs_mountain'] = UIHorizontalSlider(
            h_sl_rect, h_sl_sel, h_sl_ops, self.gui, self.ui_elements['panel'])

        # buttons
        button_rect = Rect(0, 0, 200, get_param('element_height'))
        button_rect.centerx = panel_rect.w // 2
        button_rect.y = label_rect.bottom + get_param('element_padding')
        self.ui_elements['btn_preview'] = UIButton(button_rect,
                                                   "Generate Preview",
                                                   self.gui,
                                                   self.ui_elements['panel'])
        button_rect.w = 200
        button_rect.y += get_param('element_height') + get_param(
            'element_padding')
        button_rect.centerx = (panel_rect.w // 2) - 100
        self.ui_elements['btn_back'] = UIButton(button_rect, "Back", self.gui,
                                                self.ui_elements['panel'])
        # the apply button always starts off disabled
        button_rect.centerx = (panel_rect.w // 2) + 100
        self.ui_elements['btn_next'] = UIButton(button_rect, "Next", self.gui,
                                                self.ui_elements['panel'])
        pv_rect = Rect(0, 0, 300, 300)
        pv_rect.centerx = panel_rect.w // 2
        pv_rect.y = button_rect.bottom + get_param('element_padding')
        self.ui_elements['pv_image'] = UIImage(pv_rect, self.pv_img, self.gui,
                                               self.ui_elements['panel'])
Beispiel #23
0
    def __init__(self,
                 rect: pygame.Rect,
                 manager: IUIManagerInterface,
                 window_title: str = 'File Dialog',
                 initial_file_path: Union[str, None] = None,
                 object_id: str = '#file_dialog'):

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

        minimum_dimensions = (260, 300)
        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.delete_confirmation_dialog = None  # type: Union[None, UIConfirmationDialog]

        if initial_file_path is not None:
            if exists(initial_file_path):
                self.current_directory_path = abspath(initial_file_path)
        else:
            self.current_directory_path = abspath('.')

        self.last_valid_path = None

        self.selected_file_path = None

        self.current_file_list = None  # type: Union[None, List[str]]
        self.update_current_file_list()

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

        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'
                                      })

        self.home_button = UIButton(relative_rect=pygame.Rect(10, 10, 20, 20),
                                    text='⌂',
                                    tool_tip_text='Home Directory',
                                    manager=self.ui_manager,
                                    container=self,
                                    object_id='#home_icon_button',
                                    anchors={
                                        'left': 'left',
                                        'right': 'left',
                                        'top': 'top',
                                        'bottom': 'top'
                                    })

        self.delete_button = UIButton(relative_rect=pygame.Rect(
            32, 10, 20, 20),
                                      text='⌧',
                                      tool_tip_text='Delete',
                                      manager=self.ui_manager,
                                      container=self,
                                      object_id='#delete_icon_button',
                                      anchors={
                                          'left': 'left',
                                          'right': 'left',
                                          'top': 'top',
                                          'bottom': 'top'
                                      })
        self.delete_button.disable()

        self.parent_directory_button = UIButton(
            relative_rect=pygame.Rect(54, 10, 20, 20),
            text='↑',
            tool_tip_text='Parent Directory',
            manager=self.ui_manager,
            container=self,
            object_id='#parent_icon_button',
            anchors={
                'left': 'left',
                'right': 'left',
                'top': 'top',
                'bottom': 'top'
            })

        self.refresh_button = UIButton(relative_rect=pygame.Rect(
            76, 10, 20, 20),
                                       text='⇪',
                                       tool_tip_text='Refresh Directory',
                                       manager=self.ui_manager,
                                       container=self,
                                       object_id='#refresh_icon_button',
                                       anchors={
                                           'left': 'left',
                                           'right': 'left',
                                           'top': 'top',
                                           'bottom': 'top'
                                       })

        text_line_rect = pygame.Rect(
            10, 40,
            self.get_container().relative_rect.width - 20, 25)
        self.file_path_text_line = UITextEntryLine(
            relative_rect=text_line_rect,
            manager=self.ui_manager,
            container=self,
            object_id='#file_path_text_line',
            anchors={
                'left': 'left',
                'right': 'right',
                'top': 'top',
                'bottom': 'top'
            })
        self.file_path_text_line.set_text(self.current_directory_path)

        file_selection_rect = pygame.Rect(
            10, 80,
            self.get_container().relative_rect.width - 20,
            self.get_container().relative_rect.height - 130)
        self.file_selection_list = UISelectionList(
            relative_rect=file_selection_rect,
            item_list=self.current_file_list,
            manager=self.ui_manager,
            container=self,
            object_id='#file_display_list',
            anchors={
                'left': 'left',
                'right': 'right',
                'top': 'top',
                'bottom': 'bottom'
            })
class UIColourChannelEditor(UIElement):
    """
    This colour picker specific element lets us edit a single colour channel (Red, Green, Blue,
    Hue etc). It's bundled along with the colour picker class because I don't see much use for it
    outside of a colour picker, but it still seemed sensible to make a class for a pattern in the
    colour picker that is repeated six times.

    :param relative_rect: The relative rectangle for sizing and positioning the element, relative
                          to the anchors.
    :param manager: The UI manager for the UI system.
    :param name: Name for this colour channel, (e.g 'R:' or 'B:'). Used for the label.
    :param channel_index: Index for the colour channel (e.g. red is 0, blue is 1, hue is also 0,
                          saturation is 1)
    :param value_range: Range of values for this channel (0 to 255 for R,G,B - 0 to 360 for hue, 0
                        to 100 for the rest)
    :param initial_value: Starting value for this colour channel.
    :param container: UI container for this element.
    :param parent_element: An element to parent this element, used for theming hierarchies and
                           events.
    :param object_id: A specific theming/event ID for this element.
    :param anchors: A dictionary of anchors used for setting up what this element's relative_rect
                    is relative to.
    :param visible: Whether the element is visible by default. Warning - container visibility
                    may override this.
    """
    def __init__(self,
                 relative_rect: pygame.Rect,
                 manager: IUIManagerInterface,
                 name: str,
                 channel_index: int,
                 value_range: Tuple[int, int],
                 initial_value: int,
                 container: Union[IContainerLikeInterface, None] = None,
                 parent_element: UIElement = None,
                 object_id: Union[ObjectID, str, None] = None,
                 anchors: Dict[str, str] = None,
                 visible: int = 1):

        super().__init__(relative_rect,
                         manager,
                         container,
                         starting_height=1,
                         layer_thickness=1,
                         anchors=anchors,
                         visible=visible)

        self._create_valid_ids(container=container,
                               parent_element=parent_element,
                               object_id=object_id,
                               element_id='colour_channel_editor')

        self.range = value_range
        self.current_value = initial_value
        self.channel_index = channel_index

        self.set_image(self.ui_manager.get_universal_empty_surface())

        self.element_container = UIContainer(relative_rect,
                                             self.ui_manager,
                                             container=self.ui_container,
                                             parent_element=self,
                                             anchors=anchors,
                                             visible=self.visible)

        default_sizes = {
            'space_between': 3,
            'label_width': 17,
            'entry_width': 43,
            'line_height': 29,
            'slider_height': 21,
            'slider_vert_space': 4
        }

        self.label = UILabel(pygame.Rect(0, 0, -1,
                                         default_sizes['line_height']),
                             text=name,
                             manager=self.ui_manager,
                             container=self.element_container,
                             parent_element=self,
                             anchors={
                                 'left': 'left',
                                 'right': 'left',
                                 'top': 'top',
                                 'bottom': 'bottom'
                             })

        self.entry = UITextEntryLine(pygame.Rect(-default_sizes['entry_width'],
                                                 0,
                                                 default_sizes['entry_width'],
                                                 default_sizes['line_height']),
                                     manager=self.ui_manager,
                                     container=self.element_container,
                                     parent_element=self,
                                     anchors={
                                         'left': 'right',
                                         'right': 'right',
                                         'top': 'top',
                                         'bottom': 'bottom'
                                     })

        slider_width = (self.entry.rect.left - self.label.rect.right) - (
            2 * default_sizes['space_between'])

        self.slider = UIHorizontalSlider(pygame.Rect(
            (self.label.get_abs_rect().width + default_sizes['space_between']),
            default_sizes['slider_vert_space'], slider_width,
            default_sizes['slider_height']),
                                         start_value=initial_value,
                                         value_range=value_range,
                                         manager=self.ui_manager,
                                         container=self.element_container,
                                         parent_element=self,
                                         anchors={
                                             'left': 'left',
                                             'right': 'right',
                                             'top': 'top',
                                             'bottom': 'bottom'
                                         })

        self.entry.set_allowed_characters('numbers')
        self.entry.set_text(str(initial_value))
        self.entry.set_text_length_limit(3)

    def process_event(self, event: pygame.event.Event) -> bool:
        """
        Handles events that this UI element is interested in. In this case we are responding to the
        slider being moved and the user finishing entering text in the text entry element.

        :param event: The pygame Event to process.

        :return: True if event is consumed by this element and should not be passed on to other
                 elements.

        """
        consumed_event = super().process_event(event)
        if event.type == UI_TEXT_ENTRY_FINISHED and event.ui_element == self.entry:
            int_value = self.current_value
            try:
                int_value = int(self.entry.get_text())
            except ValueError:
                int_value = 0
            finally:
                self._set_value_from_entry(int_value)

        if event.type == UI_HORIZONTAL_SLIDER_MOVED and event.ui_element == self.slider:
            int_value = self.current_value
            try:
                int_value = int(self.slider.get_current_value())
            except ValueError:
                int_value = 0
            finally:
                self._set_value_from_slider(int_value)

        return consumed_event

    def _set_value_from_slider(self, new_value: int):
        """
        For updating the value in the text entry element when we've moved the slider. Also sends
        out an event for the color picker.

        :param new_value: The new value to set.

        """
        clipped_value = min(self.range[1], max(self.range[0], new_value))
        if clipped_value != self.current_value:
            self.current_value = clipped_value
            self.entry.set_text(str(self.current_value))
            # old event - to be removed in 0.8.0
            event_data = {
                'user_type': OldType(UI_COLOUR_PICKER_COLOUR_CHANNEL_CHANGED),
                'value': self.current_value,
                'channel_index': self.channel_index,
                'ui_element': self,
                'ui_object_id': self.most_specific_combined_id
            }
            pygame.event.post(pygame.event.Event(pygame.USEREVENT, event_data))

            # new event
            event_data = {
                'value': self.current_value,
                'channel_index': self.channel_index,
                'ui_element': self,
                'ui_object_id': self.most_specific_combined_id
            }
            pygame.event.post(
                pygame.event.Event(UI_COLOUR_PICKER_COLOUR_CHANNEL_CHANGED,
                                   event_data))

    def _set_value_from_entry(self, new_value: int):
        """
        For updating the value the slider element is set to when we've edited the text entry. The
        slider may have much less precision than the text entry depending on it's available width
        so we need to be careful to make the change one way. Also sends out an event for the color
        picker and clips the value to within the allowed value range.

        :param new_value: The new value to set.

        """
        clipped_value = min(self.range[1], max(self.range[0], new_value))
        if clipped_value != new_value:
            self.entry.set_text(str(clipped_value))
        if clipped_value != self.current_value:
            self.current_value = clipped_value
            self.slider.set_current_value(self.current_value)

            # old event - to be removed in 0.8.0
            event_data = {
                'user_type': OldType(UI_COLOUR_PICKER_COLOUR_CHANNEL_CHANGED),
                'value': self.current_value,
                'channel_index': self.channel_index,
                'ui_element': self,
                'ui_object_id': self.most_specific_combined_id
            }
            colour_channel_changed_event = pygame.event.Event(
                pygame.USEREVENT, event_data)
            pygame.event.post(colour_channel_changed_event)

            event_data = {
                'value': self.current_value,
                'channel_index': self.channel_index,
                'ui_element': self,
                'ui_object_id': self.most_specific_combined_id
            }
            colour_channel_changed_event = pygame.event.Event(
                UI_COLOUR_PICKER_COLOUR_CHANNEL_CHANGED, event_data)
            pygame.event.post(colour_channel_changed_event)

    def set_value(self, new_value: int):
        """
        For when we need to set the value of the colour channel from outside, usually from
        adjusting the colour elsewhere in the colour picker. Makes sure the new value is within the
        allowed range.

        :param new_value: Value to set.

        """
        clipped_value = min(self.range[1], max(self.range[0], new_value))
        if clipped_value != self.current_value:
            self.current_value = clipped_value
            self.entry.set_text(str(self.current_value))
            self.slider.set_current_value(self.current_value)

    def set_position(self, position: Union[pygame.math.Vector2,
                                           Tuple[int, int], Tuple[float,
                                                                  float]]):
        """
        Sets the absolute screen position of this channel, updating all subordinate elements at the
        same time.

        :param position: The absolute screen position to set.

        """
        super().set_position(position)
        self.element_container.set_relative_position(
            self.relative_rect.topleft)

    def set_relative_position(self, position: Union[pygame.math.Vector2,
                                                    Tuple[int, int],
                                                    Tuple[float, float]]):
        """
        Sets the relative screen position of this channel, updating all subordinate elements at the
        same time.

        :param position: The relative screen position to set.

        """
        super().set_relative_position(position)
        self.element_container.set_relative_position(
            self.relative_rect.topleft)

    def set_dimensions(self, dimensions: Union[pygame.math.Vector2,
                                               Tuple[int, int], Tuple[float,
                                                                      float]]):
        """
        Method to directly set the dimensions of an element.

        :param dimensions: The new dimensions to set.

        """
        super().set_dimensions(dimensions)
        self.element_container.set_dimensions(self.relative_rect.size)

    def show(self):
        """
        In addition to the base UIElement.show() - call show() of the element_container
        - which will propagate to the sub-elements - label, entry and slider.
        """
        super().show()

        self.element_container.show()

    def hide(self):
        """
        In addition to the base UIElement.hide() - call hide() of the element_container
        - which will propagate to the sub-elements - label, entry and slider.
        """
        super().hide()

        self.element_container.hide()
Beispiel #25
0
    def __init__(self,
                 rect: pygame.Rect,
                 manager: IUIManagerInterface,
                 window_title: str = 'File Dialog',
                 initial_file_path: Union[str, None] = None,
                 object_id: Union[ObjectID,
                                  str] = ObjectID('#file_dialog', None),
                 allow_existing_files_only: bool = False,
                 allow_picking_directories: bool = False,
                 visible: int = 1):

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

        minimum_dimensions = (260, 300)
        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.allow_existing_files_only = allow_existing_files_only
        self.allow_picking_directories = allow_picking_directories

        self.delete_confirmation_dialog = None  # type: Union[UIConfirmationDialog, None]
        self.current_file_path = None  # type: Union[Path, None]

        if initial_file_path is not None:
            pathed_initial_file_path = Path(initial_file_path)
            if pathed_initial_file_path.exists(
            ) and not pathed_initial_file_path.is_file():
                self.current_directory_path = str(
                    pathed_initial_file_path.resolve())
                if self.allow_picking_directories:
                    self.current_file_path = self.current_directory_path
            elif pathed_initial_file_path.exists(
            ) and pathed_initial_file_path.is_file():
                self.current_file_path = pathed_initial_file_path.resolve()
                self.current_directory_path = str(
                    pathed_initial_file_path.parent.resolve())
            elif pathed_initial_file_path.parent.exists():
                self.current_directory_path = str(
                    pathed_initial_file_path.parent.resolve())
                self.current_file_path = (
                    Path(initial_file_path).parent.resolve() /
                    Path(initial_file_path).name)
        else:
            self.current_directory_path = str(Path('.').resolve())

        self.last_valid_directory_path = self.current_directory_path

        self.current_file_list = None  # type: Union[List[str], None]
        self.update_current_file_list()

        self.ok_button = UIButton(relative_rect=pygame.Rect(
            -220, -40, 100, 30),
                                  text='OK',
                                  manager=self.ui_manager,
                                  container=self,
                                  object_id='#ok_button',
                                  anchors={
                                      'left': 'right',
                                      'right': 'right',
                                      'top': 'bottom',
                                      'bottom': 'bottom'
                                  })
        if not self._validate_file_path(self.current_file_path):
            self.ok_button.disable()

        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'
                                      })

        self.home_button = UIButton(relative_rect=pygame.Rect(10, 10, 20, 20),
                                    text='⌂',
                                    tool_tip_text='Home Directory',
                                    manager=self.ui_manager,
                                    container=self,
                                    object_id='#home_icon_button',
                                    anchors={
                                        'left': 'left',
                                        'right': 'left',
                                        'top': 'top',
                                        'bottom': 'top'
                                    })

        self.delete_button = UIButton(relative_rect=pygame.Rect(
            32, 10, 20, 20),
                                      text='⌧',
                                      tool_tip_text='Delete',
                                      manager=self.ui_manager,
                                      container=self,
                                      object_id='#delete_icon_button',
                                      anchors={
                                          'left': 'left',
                                          'right': 'left',
                                          'top': 'top',
                                          'bottom': 'top'
                                      })
        if not self._validate_path_exists_and_of_allowed_type(
                self.current_file_path, allow_directories=False):
            self.delete_button.disable()

        self.parent_directory_button = UIButton(
            relative_rect=pygame.Rect(54, 10, 20, 20),
            text='↑',
            tool_tip_text='Parent Directory',
            manager=self.ui_manager,
            container=self,
            object_id='#parent_icon_button',
            anchors={
                'left': 'left',
                'right': 'left',
                'top': 'top',
                'bottom': 'top'
            })

        self.refresh_button = UIButton(relative_rect=pygame.Rect(
            76, 10, 20, 20),
                                       text='⇪',
                                       tool_tip_text='Refresh Directory',
                                       manager=self.ui_manager,
                                       container=self,
                                       object_id='#refresh_icon_button',
                                       anchors={
                                           'left': 'left',
                                           'right': 'left',
                                           'top': 'top',
                                           'bottom': 'top'
                                       })

        text_line_rect = pygame.Rect(10, 40,
                                     self.get_container().get_size()[0] - 20,
                                     25)
        self.file_path_text_line = UITextEntryLine(
            relative_rect=text_line_rect,
            manager=self.ui_manager,
            container=self,
            object_id='#file_path_text_line',
            anchors={
                'left': 'left',
                'right': 'right',
                'top': 'top',
                'bottom': 'top'
            })
        if self.current_file_path is not None:
            self.file_path_text_line.set_text(str(self.current_file_path))
            self._highlight_file_name_for_editing()
        else:
            self.file_path_text_line.set_text(str(self.current_directory_path))

        file_selection_rect = pygame.Rect(
            10, 80,
            self.get_container().get_size()[0] - 20,
            self.get_container().get_size()[1] - 130)
        self.file_selection_list = UISelectionList(
            relative_rect=file_selection_rect,
            item_list=self.current_file_list,
            manager=self.ui_manager,
            container=self,
            object_id='#file_display_list',
            anchors={
                'left': 'left',
                'right': 'right',
                'top': 'top',
                'bottom': 'bottom'
            })
Beispiel #26
0
class IntroScreen(object):
    def __init__(self):
        pygame.init()
        self.size = [INTRO_SCREEN_WIDTH, INTRO_SCREEN_HEIGHT]
        self.screen = pygame.display.set_mode(self.size)
        self.con_win = None
        self.game_level = 4
        self.game = None
        self.start_game = False
        self.game_nb_players = 4  # TODO The max number of players should be in function of the size of the desk
        self.game_nb_online_players = 1
        self.nb_p_c = 1
        # self.block_list
        self.player_name = "John"
        # self.player_name = "IA Show"
        self.player_type = "offline"
        self.host_address = "localhost"
        self.survival_mode = True
        self.all_sprites_list = pygame.sprite.Group()
        self.block_list = pygame.sprite.Group()
        self.clicked = False
        self.ui_manager = pygame_gui.UIManager(
            (INTRO_SCREEN_WIDTH, INTRO_SCREEN_HEIGHT))
        self.ui_manager.preload_fonts([{
            'name': 'fira_code',
            'point_size': 10,
            'style': 'bold'
        }, {
            'name': 'fira_code',
            'point_size': 10,
            'style': 'regular'
        }, {
            'name': 'fira_code',
            'point_size': 10,
            'style': 'italic'
        }, {
            'name': 'fira_code',
            'point_size': 14,
            'style': 'italic'
        }, {
            'name': 'fira_code',
            'point_size': 14,
            'style': 'bold'
        }, {
            'name': 'fira_code',
            'point_size': 14,
            'style': 'bold_italic'
        }])
        step = 40
        s = [150, 35]
        self.name_label = UILabel(pygame.rect.Rect((0, step), s),
                                  "Name",
                                  manager=self.ui_manager)
        self.name_value = UITextEntryLine(
            pygame.Rect((self.name_label.relative_rect.width,
                         self.name_label.relative_rect.y), (200, -1)),
            self.ui_manager)
        self.name_value.set_text(self.player_name)
        # The level
        self.game_level_label = UILabel(pygame.rect.Rect((0, step * 2), s),
                                        "Level",
                                        manager=self.ui_manager)
        self.game_level_drop = UIDropDownMenu(
            [str(i) for i in range(1, 5, 1)], f"{self.game_level}",
            pygame.rect.Rect(((s[0] - step) // 2, step * 3),
                             (50, 35)), self.ui_manager)
        self.nb_players_label = UILabel(pygame.rect.Rect(
            (s[0], self.game_level_label.relative_rect.y), s),
                                        "NB players",
                                        manager=self.ui_manager)
        self.nb_players_drop = UIDropDownMenu([str(i) for i in range(2, 7, 1)],
                                              f"{self.game_nb_players}",
                                              pygame.Rect(
                                                  (int(1.3 * s[0]), step * 3),
                                                  (50, 35)), self.ui_manager)

        self.nb_p_c_label = UILabel(pygame.rect.Rect(
            (2 * s[0], self.game_level_label.relative_rect.y), s),
                                    "NB playing cards",
                                    manager=self.ui_manager)

        self.nb_p_c_players_drop = UIDropDownMenu(
            [str(i) for i in range(1, 5, 1)], f"{self.nb_p_c}",
            pygame.Rect((int(2.3 * s[0]), step * 3),
                        (50, 35)), self.ui_manager)
        self.survival_label = UILabel(pygame.rect.Rect(
            (3 * s[0], self.game_level_label.relative_rect.y), s),
                                      "Survival mode",
                                      manager=self.ui_manager)

        self.survival_drop = UIDropDownMenu(
            ["yes", "no"], f"{'yes' if self.survival_mode else 'no'}",
            pygame.Rect((int(3.3 * s[0]), step * 3),
                        (60, 35)), self.ui_manager)

        self.start_game_btn = UIButton(
            pygame.Rect((INTRO_SCREEN_WIDTH - 200, INTRO_SCREEN_HEIGHT - 50),
                        (100, 40)), 'START', self.ui_manager)
        self.resume_game_btn = UIButton(
            pygame.Rect(
                (INTRO_SCREEN_WIDTH // 2 - 50, INTRO_SCREEN_HEIGHT - 50),
                (100, 40)), 'RESUME', self.ui_manager)
        self.quit_game_btn = UIButton(
            pygame.Rect((100, INTRO_SCREEN_HEIGHT - 50), (100, 40)), 'QUIT',
            self.ui_manager)
        UILabel(pygame.rect.Rect((10, int(step * 6.5 - s[1])), s),
                "On-line Settings",
                manager=self.ui_manager)
        self.online_panel = UIPanel(pygame.rect.Rect(
            (10, int(step * 6.5)), (INTRO_SCREEN_WIDTH - 20, step * 5)),
                                    starting_layer_height=4,
                                    manager=self.ui_manager)

        self.nb_online_players_label = UILabel(pygame.rect.Rect((s[0], 0), s),
                                               "Online players",
                                               manager=self.ui_manager,
                                               container=self.online_panel)

        self.nb_online_players_drop = UIDropDownMenu(
            [str(i) for i in range(1, 6, 1)],
            f"{self.game_nb_online_players}",
            pygame.Rect((int(1.3 * (s[0])), step), (55, 35)),
            self.ui_manager,
            container=self.online_panel)
        self.player_type_label = UILabel(pygame.rect.Rect((0, 0), s),
                                         "Player type",
                                         manager=self.ui_manager,
                                         container=self.online_panel)
        self.player_type_drop = UIDropDownMenu(["server", "client", "offline"],
                                               f"{self.player_type}",
                                               pygame.Rect(
                                                   (int(0.17 * s[0]), step),
                                                   (100, 35)),
                                               self.ui_manager,
                                               container=self.online_panel)
        self.host_address_label = UILabel(pygame.rect.Rect((s[0], 0), s),
                                          "Host address",
                                          manager=self.ui_manager,
                                          container=self.online_panel)
        self.host_address_entry = UITextEntryLine(pygame.Rect((s[0], step),
                                                              (150, 35)),
                                                  self.ui_manager,
                                                  container=self.online_panel)
        self.host_address_entry.set_text(self.host_address)
        if self.player_type != "client":
            # self.host_address_label.is_enabled = False
            # self.host_address_entry.is_enabled = False

            self.game_level_drop.show()
            self.game_level_label.show()
            self.nb_players_drop.show()
            self.nb_players_label.show()
            self.nb_p_c_players_drop.show()
            self.nb_p_c_label.show()
            self.survival_drop.show()
            self.survival_label.show()

            self.host_address_entry.hide()
            self.host_address_label.hide()
        else:
            # self.host_address_label.is_enabled = True
            # self.host_address_entry.is_enabled = True

            self.game_level_drop.hide()
            self.game_level_label.hide()
            self.nb_players_drop.hide()
            self.nb_players_label.hide()
            self.nb_p_c_players_drop.hide()
            self.nb_p_c_label.hide()
            self.survival_drop.hide()
            self.survival_label.hide()

            self.host_address_label.show()
            self.host_address_entry.show()

        if self.player_type != "server":
            # self.nb_online_players_drop.is_enabled = False
            self.nb_online_players_drop.hide()
            self.nb_online_players_label.hide()
        else:
            # self.nb_online_players_drop.is_enabled = True
            self.nb_online_players_drop.show()
            self.nb_online_players_label.show()

    def run_game(self):
        done = self.game.run()
        if not done:
            pygame.mouse.set_visible(True)
            self.screen = pygame.display.set_mode(self.size)
        else:
            return True

    def process_events(self):
        """ Process all of the events. Return a "True" if we need
            to close the window. """

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                return True
            if event.type == pygame.MOUSEBUTTONDOWN:
                self.clicked = True
            if event.type == pygame.USEREVENT:
                if event.user_type == pygame_gui.UI_BUTTON_PRESSED or self.start_game:
                    if event.ui_element == self.resume_game_btn and self.game:
                        done = self.game.resume()
                        if not done:
                            pygame.mouse.set_visible(True)
                            self.screen = pygame.display.set_mode(self.size)
                        else:
                            return True

                    if event.ui_element == self.start_game_btn or self.start_game:
                        if self.player_type == "client":
                            _type = self.host_address
                        elif self.player_type == "server":
                            _type = self.player_type
                        else:
                            _type = None
                        g_args = {
                            "player_name": self.player_name,
                            "nb_players": self.game_nb_players,
                            "nb_online": self.game_nb_online_players,
                            "level": self.game_level,
                            "nb_playing_cards": self.nb_p_c,
                            "_type": _type,
                            "survival_mode": self.survival_mode,
                        }
                        if self.player_type == "server":
                            if self.con_win is None or not self.con_win.alive(
                            ):
                                self.con_win = ConnectionWindow.ConnectionWindow(
                                    g_args, self,
                                    pygame.rect.Rect(
                                        (INTRO_SCREEN_WIDTH // 4, 0),
                                        (INTRO_SCREEN_WIDTH // 2,
                                         DESK_HEIGHT)), self.ui_manager)
                        else:
                            self.game = CardsGame.CardsGame(**g_args)

                        if self.game:
                            done = self.game.run()
                            if not done:
                                pygame.mouse.set_visible(True)
                                self.screen = pygame.display.set_mode(
                                    self.size)
                            else:
                                return True

                    if event.ui_element == self.quit_game_btn:
                        return True
                if event.user_type == pygame_gui.UI_TEXT_ENTRY_CHANGED:
                    if event.ui_element == self.name_value:
                        self.player_name = event.text
                    if event.ui_element == self.host_address_entry:
                        self.host_address = event.text
                if event.user_type == pygame_gui.UI_DROP_DOWN_MENU_CHANGED:
                    if event.ui_element == self.survival_drop:
                        self.survival_mode = self.survival_drop.selected_option == "yes"
                    if event.ui_element == self.game_level_drop:
                        self.game_level = int(
                            self.game_level_drop.selected_option)
                    if event.ui_element == self.nb_players_drop:
                        self.game_nb_players = int(
                            self.nb_players_drop.selected_option)
                    if event.ui_element == self.nb_online_players_drop:
                        self.game_nb_online_players = int(
                            self.nb_online_players_drop.selected_option)
                    if event.ui_element == self.nb_p_c_players_drop:
                        self.nb_p_c = int(
                            self.nb_p_c_players_drop.selected_option)
                    if event.ui_element == self.player_type_drop:
                        self.player_type = self.player_type_drop.selected_option

                        if self.player_type != "client":
                            # self.host_address_label.is_enabled = False
                            # self.host_address_entry.is_enabled = False

                            self.game_level_drop.show()
                            self.game_level_label.show()
                            self.nb_players_drop.show()
                            self.nb_players_label.show()
                            self.nb_p_c_players_drop.show()
                            self.nb_p_c_label.show()
                            self.survival_drop.show()
                            self.survival_label.show()

                            self.host_address_entry.hide()
                            self.host_address_label.hide()
                        else:
                            # self.host_address_label.is_enabled = True
                            # self.host_address_entry.is_enabled = True

                            self.game_level_drop.hide()
                            self.game_level_label.hide()
                            self.nb_players_drop.hide()
                            self.nb_players_label.hide()
                            self.nb_p_c_players_drop.hide()
                            self.nb_p_c_label.hide()
                            self.survival_drop.hide()
                            self.survival_label.hide()

                            self.host_address_label.show()
                            self.host_address_entry.show()

                        if self.player_type != "server":
                            # self.nb_online_players_drop.is_enabled = False
                            self.nb_online_players_drop.hide()
                            self.nb_online_players_label.hide()
                        else:
                            # self.nb_online_players_drop.is_enabled = True
                            self.nb_online_players_drop.show()
                            self.nb_online_players_label.show()
            self.ui_manager.process_events(event)

        return False

    def run_logic(self):
        """
        This method is run each time through the frame. It
        updates positions and checks for collisions.
        """
        # Move all the sprites
        self.all_sprites_list.update()
        self.block_list.update()
        if self.clicked:
            col = (randint(0, 255), randint(0, 255), randint(0, 255))
            block = Block(col)
            pos = pygame.mouse.get_pos()
            x = pos[0]
            y = pos[1]
            block.rect.x = x
            block.rect.y = y
            self.block_list.add(block)
            self.all_sprites_list.add(block)
            if len(self.block_list) > 20:
                self.block_list.sprites()[0].kill()
        self.clicked = False

    def display_frame(self, time_delta, screen):
        """ Display everything to the screen for the game. """
        screen.fill(self.ui_manager.get_theme().get_colour('dark_bg'))
        if not self.game:
            self.resume_game_btn.disable()
        elif not self.resume_game_btn.is_enabled:
            self.resume_game_btn.enable()
        # if self.player_type != "server":
        #     self.host_address_label.ui_manager = None
        #     self.host_address_label.ui_container = None
        #     self.host_address_entry.ui_manager = None
        #     self.host_address_entry.ui_container = None

        self.ui_manager.update(time_delta)
        self.ui_manager.draw_ui(screen)

        self.all_sprites_list.draw(screen)
        pygame.display.flip()

    def run(self):
        """ Main program function. """
        # Initialize Pygame and set up the window
        pygame.display.set_caption("Setup")

        # Create our objects and set the data
        done = False
        clock = pygame.time.Clock()

        # intro_game = IntroScreen()

        # Main game loop
        while not done:
            time_delta = clock.tick() / 1000.0
            # Process events (keystrokes, mouse clicks, etc)
            done = self.process_events()

            if not done:
                # Update object positions, check for collisions
                # self.run_logic()
                # Draw the current frame
                self.display_frame(time_delta, self.screen)

            # Pause for the next frame
            # clock.tick(60)

        # Close window and exit
        pygame.quit()
    def __init__(self,
                 relative_rect: pygame.Rect,
                 manager: IUIManagerInterface,
                 name: str,
                 channel_index: int,
                 value_range: Tuple[int, int],
                 initial_value: int,
                 container: Union[IContainerLikeInterface, None] = None,
                 parent_element: UIElement = None,
                 object_id: Union[ObjectID, str, None] = None,
                 anchors: Dict[str, str] = None,
                 visible: int = 1):

        super().__init__(relative_rect,
                         manager,
                         container,
                         starting_height=1,
                         layer_thickness=1,
                         anchors=anchors,
                         visible=visible)

        self._create_valid_ids(container=container,
                               parent_element=parent_element,
                               object_id=object_id,
                               element_id='colour_channel_editor')

        self.range = value_range
        self.current_value = initial_value
        self.channel_index = channel_index

        self.set_image(self.ui_manager.get_universal_empty_surface())

        self.element_container = UIContainer(relative_rect,
                                             self.ui_manager,
                                             container=self.ui_container,
                                             parent_element=self,
                                             anchors=anchors,
                                             visible=self.visible)

        default_sizes = {
            'space_between': 3,
            'label_width': 17,
            'entry_width': 43,
            'line_height': 29,
            'slider_height': 21,
            'slider_vert_space': 4
        }

        self.label = UILabel(pygame.Rect(0, 0, -1,
                                         default_sizes['line_height']),
                             text=name,
                             manager=self.ui_manager,
                             container=self.element_container,
                             parent_element=self,
                             anchors={
                                 'left': 'left',
                                 'right': 'left',
                                 'top': 'top',
                                 'bottom': 'bottom'
                             })

        self.entry = UITextEntryLine(pygame.Rect(-default_sizes['entry_width'],
                                                 0,
                                                 default_sizes['entry_width'],
                                                 default_sizes['line_height']),
                                     manager=self.ui_manager,
                                     container=self.element_container,
                                     parent_element=self,
                                     anchors={
                                         'left': 'right',
                                         'right': 'right',
                                         'top': 'top',
                                         'bottom': 'bottom'
                                     })

        slider_width = (self.entry.rect.left - self.label.rect.right) - (
            2 * default_sizes['space_between'])

        self.slider = UIHorizontalSlider(pygame.Rect(
            (self.label.get_abs_rect().width + default_sizes['space_between']),
            default_sizes['slider_vert_space'], slider_width,
            default_sizes['slider_height']),
                                         start_value=initial_value,
                                         value_range=value_range,
                                         manager=self.ui_manager,
                                         container=self.element_container,
                                         parent_element=self,
                                         anchors={
                                             'left': 'left',
                                             'right': 'right',
                                             'top': 'top',
                                             'bottom': 'bottom'
                                         })

        self.entry.set_allowed_characters('numbers')
        self.entry.set_text(str(initial_value))
        self.entry.set_text_length_limit(3)
Beispiel #28
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()