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