def test_process_event_text_ctrl_x(self, _init_pygame: None,
                                       default_ui_manager: UIManager,
                                       _display_surface_return_none: None):
        text_entry = UITextEntryLine(relative_rect=pygame.Rect(
            100, 100, 200, 30),
                                     manager=default_ui_manager)

        text_entry.set_text('dan')
        text_entry.select()

        processed_key_event = text_entry.process_event(
            pygame.event.Event(pygame.KEYDOWN, {
                'key': pygame.K_a,
                'mod': pygame.KMOD_CTRL,
                'unicode': 'a'
            }))

        text_entry.process_event(
            pygame.event.Event(pygame.KEYDOWN, {
                'key': pygame.K_x,
                'mod': pygame.KMOD_CTRL,
                'unicode': 'x'
            }))

        text_entry.process_event(
            pygame.event.Event(pygame.KEYDOWN, {
                'key': pygame.K_v,
                'mod': pygame.KMOD_CTRL,
                'unicode': 'v'
            }))

        assert processed_key_event and clipboard_paste() == 'dan'
Пример #2
0
    def _process_paste_event(self, event: pygame.event.Event) -> bool:
        """
        Process a paste shortcut event. (CTRL+ V)

        :param event: The event to process.

        :return: True if the event is consumed.

        """
        consumed_event = False
        if event.key == pygame.K_v and event.mod & pygame.KMOD_CTRL:
            new_text = clipboard_paste()
            if self.validate_text_string(new_text):
                if abs(self.select_range[0] - self.select_range[1]) > 0:
                    low_end = min(self.select_range[0], self.select_range[1])
                    high_end = max(self.select_range[0], self.select_range[1])
                    final_text = self.text[:low_end] + new_text + self.text[high_end:]
                    within_length_limit = True
                    if self.length_limit is not None and len(final_text) > self.length_limit:
                        within_length_limit = False
                    if within_length_limit:
                        self.text = final_text
                        if self.drawable_shape is not None:
                            self.drawable_shape.text_box_layout.delete_selected_text()
                            self.drawable_shape.apply_active_text_changes()
                        display_new_text = new_text
                        if self.is_text_hidden:
                            display_new_text = self.hidden_text_char * len(new_text)
                        if self.drawable_shape is not None:
                            self.drawable_shape.insert_text(display_new_text, low_end)
                        self.edit_position = low_end + len(new_text)
                        if self.drawable_shape is not None:
                            self.drawable_shape.text_box_layout.set_cursor_position(
                                self.edit_position)
                            self.drawable_shape.apply_active_text_changes()
                        self.select_range = [0, 0]
                        self.cursor_has_moved_recently = True
                elif len(new_text) > 0:
                    final_text = (self.text[:self.edit_position] +
                                  new_text +
                                  self.text[self.edit_position:])
                    within_length_limit = True
                    if self.length_limit is not None and len(final_text) > self.length_limit:
                        within_length_limit = False
                    if within_length_limit:
                        self.text = final_text
                        display_new_text = new_text
                        if self.is_text_hidden:
                            display_new_text = self.hidden_text_char * len(new_text)
                        if self.drawable_shape is not None:
                            self.drawable_shape.insert_text(display_new_text, self.edit_position)
                        self.edit_position += len(new_text)
                        if self.drawable_shape is not None:
                            self.drawable_shape.text_box_layout.set_cursor_position(
                                self.edit_position)
                            self.drawable_shape.apply_active_text_changes()
                        self.cursor_has_moved_recently = True
                consumed_event = True
        return consumed_event
Пример #3
0
    def _process_paste_event(self, event: pygame.event.Event) -> bool:
        """
        Process a paste shortcut event. (CTRL+ V)

        :param event: The event to process.

        :return: True if the event is consumed.

        """
        consumed_event = False
        if event.key == pygame.K_v and event.mod & pygame.KMOD_CTRL:
            new_text = clipboard_paste()
            if self.validate_text_string(new_text):
                if abs(self.select_range[0] - self.select_range[1]) > 0:
                    low_end = min(self.select_range[0], self.select_range[1])
                    high_end = max(self.select_range[0], self.select_range[1])
                    final_text = self.text[:low_end] + new_text + self.text[
                        high_end:]
                    within_length_limit = True
                    if self.length_limit is not None and len(
                            final_text) > self.length_limit:
                        within_length_limit = False
                    if within_length_limit:
                        self.text = final_text
                        self.edit_position = low_end + len(new_text)
                        self.select_range = [0, 0]
                        self.cursor_has_moved_recently = True
                elif len(new_text) > 0:
                    final_text = (self.text[:self.edit_position] + new_text +
                                  self.text[self.edit_position:])
                    within_length_limit = True
                    if self.length_limit is not None and len(
                            final_text) > self.length_limit:
                        within_length_limit = False
                    if within_length_limit:
                        self.text = final_text
                        self.edit_position += len(new_text)
                        self.cursor_has_moved_recently = True
                consumed_event = True
        return consumed_event
    def test_process_event_text_ctrl_c(self, _init_pygame: None,
                                       _display_surface_return_none: None):
        manager = UIManager(
            (800, 600),
            os.path.join("tests", "data", "themes",
                         "ui_text_entry_line_non_default_2.json"))
        text_entry = UITextEntryLine(relative_rect=pygame.Rect(
            100, 100, 200, 30),
                                     manager=manager)

        text_entry.set_text('dan')
        text_entry.select()
        text_entry.select_range = [0, 3]

        processed_key_event = text_entry.process_event(
            pygame.event.Event(pygame.KEYDOWN, {
                'key': pygame.K_c,
                'mod': pygame.KMOD_CTRL,
                'unicode': 'c'
            }))
        text_entry.cursor_on = True
        text_entry.redraw_cursor()

        assert processed_key_event and clipboard_paste() == 'dan'
Пример #5
0
    def process_event(self, event: pygame.event.Event) -> bool:
        """
        Allows the text entry box to react to input events, which is it's primary function. The entry element reacts to
        various types of mouse clicks (double click selecting words, drag select), keyboard combos (CTRL+C, CTRL+V,
        CTRL+X, CTRL+A), individual editing keys (Backspace, Delete, Left & Right arrows) and other keys for inputting
        letters, symbols and numbers.

        :param event: The current event to consider reacting to.
        :return bool: Returns True if we've done something with the input event.
        """
        processed_event = False
        if event.type == pygame.MOUSEBUTTONDOWN:
            if event.button == 1:
                mouse_x, mouse_y = event.pos
                if self.rect.collidepoint(mouse_x, mouse_y):
                    if self.double_click_started and self.double_click_select_time_acc < self.double_click_select_time:
                        self.double_click_started = False
                        pattern = re.compile(r"[\w']+")
                        index = min(self.edit_position, len(self.text) - 1)
                        if index > 0:
                            char = self.text[index]
                            while not pattern.match(char):
                                index -= 1
                                if index > 0:
                                    char = self.text[index]
                                else:
                                    break
                            while pattern.match(char):
                                index -= 1
                                if index > 0:
                                    char = self.text[index]
                                else:
                                    break
                            if index > 0:
                                start_select_index = index + 1
                            else:
                                start_select_index = index
                            index += 1
                            char = self.text[index]
                            while index < len(
                                    self.text) and pattern.match(char):
                                index += 1
                                if index < len(self.text):
                                    char = self.text[index]
                            end_select_index = index

                            self.select_range[0] = start_select_index
                            self.select_range[1] = end_select_index
                            self.edit_position = end_select_index
                            self.cursor_has_moved_recently = True
                    else:
                        self.double_click_started = True
                        self.edit_position = self.find_edit_position_from_pixel_pos(
                            self.start_text_offset + mouse_x)
                        self.select_range[0] = self.edit_position
                        self.select_range[1] = self.edit_position
                        self.cursor_has_moved_recently = True
                        self.selection_in_progress = True
                        self.double_click_select_time_acc = 0.0

                    processed_event = True
        if event.type == pygame.MOUSEBUTTONUP:
            if event.button == 1:
                mouse_x, mouse_y = event.pos
                if self.rect.collidepoint(mouse_x, mouse_y):
                    processed_event = True
                    new_edit_pos = self.find_edit_position_from_pixel_pos(
                        self.start_text_offset + mouse_x)
                    if new_edit_pos != self.edit_position:
                        self.cursor_has_moved_recently = True
                        self.select_range[1] = self.edit_position
                    self.selection_in_progress = False
                else:
                    self.selection_in_progress = False

        if self.selected:
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_RETURN:
                    entry_finished_event = pygame.event.Event(
                        pygame.USEREVENT, {
                            'user_type': 'ui_text_entry_finished',
                            'text': self.text,
                            'ui_element': self,
                            'ui_object_id': self.object_ids[-1]
                        })
                    pygame.event.post(entry_finished_event)
                elif event.key == pygame.K_a and event.mod & pygame.KMOD_CTRL:
                    self.select_range = [0, len(self.text)]
                    self.edit_position = len(self.text)
                    self.cursor_has_moved_recently = True
                elif event.key == pygame.K_x and event.mod & pygame.KMOD_CTRL:
                    if abs(self.select_range[0] - self.select_range[1]) > 0:
                        low_end = min(self.select_range[0],
                                      self.select_range[1])
                        high_end = max(self.select_range[0],
                                       self.select_range[1])
                        clipboard_copy(self.text[low_end:high_end])
                        self.text = self.text[:low_end] + self.text[high_end:]
                        self.edit_position = low_end
                        self.select_range = [0, 0]
                        self.cursor_has_moved_recently = True
                elif event.key == pygame.K_c and event.mod & pygame.KMOD_CTRL:
                    if abs(self.select_range[0] - self.select_range[1]) > 0:
                        low_end = min(self.select_range[0],
                                      self.select_range[1])
                        high_end = max(self.select_range[0],
                                       self.select_range[1])
                        clipboard_copy(self.text[low_end:high_end])
                elif event.key == pygame.K_v and event.mod & pygame.KMOD_CTRL:
                    new_text = clipboard_paste()
                    if self.validate_text_string(new_text):
                        if abs(self.select_range[0] -
                               self.select_range[1]) > 0:
                            low_end = min(self.select_range[0],
                                          self.select_range[1])
                            high_end = max(self.select_range[0],
                                           self.select_range[1])
                            final_text = self.text[:
                                                   low_end] + new_text + self.text[
                                                       high_end:]
                            within_length_limit = True
                            if self.length_limit is not None:
                                if len(final_text) > self.length_limit:
                                    within_length_limit = False
                            if within_length_limit:
                                self.text = final_text
                                self.edit_position = low_end + len(new_text)
                                self.select_range = [0, 0]
                                self.cursor_has_moved_recently = True
                        elif len(new_text) > 0:
                            final_text = self.text[:self.
                                                   edit_position] + new_text + self.text[
                                                       self.edit_position:]
                            within_length_limit = True
                            if self.length_limit is not None:
                                if len(final_text) > self.length_limit:
                                    within_length_limit = False
                            if within_length_limit:
                                self.text = final_text
                                self.edit_position += len(new_text)
                                self.cursor_has_moved_recently = True
                        processed_event = True
                elif event.key == pygame.K_BACKSPACE:
                    if abs(self.select_range[0] - self.select_range[1]) > 0:
                        low_end = min(self.select_range[0],
                                      self.select_range[1])
                        high_end = max(self.select_range[0],
                                       self.select_range[1])
                        self.text = self.text[:low_end] + self.text[high_end:]
                        self.edit_position = low_end
                        self.select_range = [0, 0]
                        self.cursor_has_moved_recently = True
                    elif self.edit_position > 0:
                        if self.start_text_offset > 0:
                            self.start_text_offset -= self.font.size(
                                self.text[self.edit_position - 1])[0]
                        self.text = self.text[:self.edit_position -
                                              1] + self.text[self.
                                                             edit_position:]
                        self.edit_position -= 1
                        self.cursor_has_moved_recently = True
                    processed_event = True
                elif event.key == pygame.K_DELETE:
                    if abs(self.select_range[0] - self.select_range[1]) > 0:
                        low_end = min(self.select_range[0],
                                      self.select_range[1])
                        high_end = max(self.select_range[0],
                                       self.select_range[1])
                        self.text = self.text[:low_end] + self.text[high_end:]
                        self.edit_position = low_end
                        self.select_range = [0, 0]
                        self.cursor_has_moved_recently = True
                    elif self.edit_position < len(self.text):
                        self.text = self.text[:self.edit_position] + self.text[
                            self.edit_position + 1:]
                        self.edit_position = self.edit_position
                        self.cursor_has_moved_recently = True
                    processed_event = True
                elif event.key == pygame.K_LEFT:
                    if abs(self.select_range[0] - self.select_range[1]) > 0:
                        self.edit_position = min(self.select_range[0],
                                                 self.select_range[1])
                        self.select_range = [0, 0]
                        self.cursor_has_moved_recently = True
                    elif self.edit_position > 0:
                        self.edit_position -= 1
                        self.cursor_has_moved_recently = True
                    processed_event = True
                elif event.key == pygame.K_RIGHT:
                    if abs(self.select_range[0] - self.select_range[1]) > 0:
                        self.edit_position = max(self.select_range[0],
                                                 self.select_range[1])
                        self.select_range = [0, 0]
                        self.cursor_has_moved_recently = True
                    elif self.edit_position < len(self.text):
                        self.edit_position += 1
                        self.cursor_has_moved_recently = True
                    processed_event = True
                else:
                    within_length_limit = True
                    if self.length_limit is not None:
                        if len(self.text) >= self.length_limit:
                            within_length_limit = False
                    if within_length_limit:
                        character = event.unicode
                        char_metrics = self.font.metrics(character)
                        if len(char_metrics
                               ) > 0 and char_metrics[0] is not None:
                            valid_character = True
                            if self.allowed_characters is not None:
                                if character not in self.allowed_characters:
                                    valid_character = False
                            if self.forbidden_characters is not None:
                                if character in self.forbidden_characters:
                                    valid_character = False
                            if valid_character:
                                if abs(self.select_range[0] -
                                       self.select_range[1]) > 0:
                                    low_end = min(self.select_range[0],
                                                  self.select_range[1])
                                    high_end = max(self.select_range[0],
                                                   self.select_range[1])
                                    self.text = self.text[:
                                                          low_end] + character + self.text[
                                                              high_end:]
                                    self.edit_position = low_end + 1
                                    self.select_range = [0, 0]
                                else:
                                    start_str = self.text[:self.edit_position]
                                    end_str = self.text[self.edit_position:]
                                    self.text = start_str + character + end_str
                                    self.edit_position += 1
                                self.cursor_has_moved_recently = True
                                processed_event = True
        return processed_event