예제 #1
0
    def _process_keyboard_shortcut_event(self,
                                         event: pygame.event.Event) -> bool:
        """
        Check if event is one of the CTRL key keyboard shortcuts.

        :param event: event to process.

        :return: True if event consumed.

        """
        consumed_event = False
        if 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
            consumed_event = 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
                consumed_event = 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])
                consumed_event = True
        elif self._process_paste_event(event):
            consumed_event = True
        return consumed_event
    def test_process_event_text_ctrl_v_nothing(
            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)

        clipboard_copy('')
        text_entry.set_text('dan')
        text_entry.focus()
        text_entry.select_range = [0, 0]
        processed_key_event = text_entry.process_event(
            pygame.event.Event(pygame.KEYDOWN, {
                'key': pygame.K_v,
                'mod': pygame.KMOD_CTRL,
                'unicode': 'v'
            }))

        assert processed_key_event and text_entry.get_text() == 'dan'
예제 #3
0
    def _process_keyboard_shortcut_event(self, event: pygame.event.Event) -> bool:
        """
        Check if event is one of the CTRL key keyboard shortcuts.

        :param event: event to process.

        :return: True if event consumed.

        """
        consumed_event = False
        if 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
            consumed_event = True
        elif event.key == pygame.K_x and event.mod & pygame.KMOD_CTRL and not self.is_text_hidden:
            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])
                if self.drawable_shape is not None:
                    self.drawable_shape.text_box_layout.delete_selected_text()
                    self.drawable_shape.apply_active_text_changes()
                self.edit_position = low_end
                self.text = self.text[:low_end] + self.text[high_end:]
                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
                consumed_event = True
        elif event.key == pygame.K_c and event.mod & pygame.KMOD_CTRL and not self.is_text_hidden:
            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])
                consumed_event = True
        elif self._process_paste_event(event):
            consumed_event = True
        return consumed_event
예제 #4
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